Android переднего плана службы, которые могут быть связаны - PullRequest
7 голосов
/ 21 марта 2011

Как правильно выполнять обслуживание переднего плана, которое я могу позже связать с ним? Я ознакомился с демонстрацией Android API, которая включает пример создания службы переднего плана. Нет примера запуска службы привязки к ней одновременно.

Я хочу увидеть один хороший пример сервиса музыкального плеера с активностью, связанной с ним.

Есть ли?

Я хочу сделать что-то вроде:

  • Когда программа запускается первой (первая означает, что служба еще не запущена), я хочу запустить службу переднего плана, которая выполняет всю работу. Пользовательский интерфейс (активность) просто для управления этой работой
  • Если пользователь нажимает кнопку «Домой», служба должна оставаться в рабочем состоянии (и должно присутствовать уведомление на панели)
  • Теперь, если пользователь щелкнет по уведомлению в панели уведомлений, действие должно начаться и привязаться к сервису (или что-то подобное, правильный путь), и пользователь получит контроль над заданием.
  • Если активность активна и пользователь нажимает кнопку «Назад», активность должна быть уничтожена, а служба должна быть уничтожена.

Какие методы мне нужно переопределить, чтобы выполнить эту задачу? Как Android это делает?

Ответы [ 2 ]

10 голосов
/ 22 марта 2011

до froyo в Service было установлено setForeground (true), которое было легко, но также легко злоупотреблять.

Теперь есть службы startForeGround, для которых требуется активировать уведомление (чтобы пользователь мог видеть, что запущена служба foregroundservice).

я создал этот класс для управления им:

public class NotificationUpdater {
    public static void turnOnForeground(Service srv,int notifID,NotificationManager mNotificationManager,Notification notif) {
        try {
            Method m = Service.class.getMethod("startForeground", new Class[] {int.class, Notification.class});
            m.invoke(srv, notifID, notif);
        } catch (Exception e) {
            srv.setForeground(true);
            mNotificationManager.notify(notifID, notif);
        }
    } 

    public static void turnOffForeground(Service srv,int notifID,NotificationManager mNotificationManager) {
        try {
            Method m = Service.class.getMethod("stopForeground", new Class[] {boolean.class});
            m.invoke(srv, true);
        } catch (Exception e) {
            srv.setForeground(false);
            mNotificationManager.cancel(notifID);
        }
    }
}

тогда для моего медиапроигрывателя это обновление уведомляет - обратите внимание, что служба переднего плана требуется только во время воспроизведения мультимедиа и должна оставаться включенной после ее остановки, это плохая практика.

private void updateNotification(){
    boolean playing = ((mFGPlayerBean.getState()==MediaPlayerWrapper.STATE_PLAYING) || 
                        (mBGPlayerBean.getState()==MediaPlayerWrapper.STATE_PLAYING));
    if (playing) {
        Notification notification = getNotification();
        NotificationUpdater.turnOnForeground(this,Globals.NOTIFICATION_ID_MP,mNotificationManager,notification);
    } else {
        NotificationUpdater.turnOffForeground(this,Globals.NOTIFICATION_ID_MP,mNotificationManager);
    }
}

что касается связывания - вы просто связываетесь обычным способом в своей деятельности при запуске, вы просто делаете вызов bindService, как если бы вы связывались с любым сервисом (не имеет значения, будет ли он на переднем плане или нет)

MediaPlayerService mpService=null;
@Override
protected void onEWCreate(Bundle savedInstanceState) {
     Intent intent = new Intent(this, MediaPlayerService.class);
     startService(intent);
}

@Override
protected void onStart() {
    // assume startService has been called already
    if (mpService==null) {
        Intent intentBind = new Intent(this, MediaPlayerService.class);
        bindService(intentBind, mConnection, 0);
    }
}

private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        mpService = ((MediaPlayerService.MediaBinder)service).getService();
    }

    public void onServiceDisconnected(ComponentName className) {
        mpService = null;
    }
};
0 голосов
/ 15 апреля 2011

Для выполнения поставленной задачи единственное, что мне нужно сделать, это добавить следующее свойство в AndroidManifest.xml к определению моей активности

android:launchMode="singleTop"

Вот и все.

Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...