Android上的持久服务

时间:2013-08-16 10:58:30

标签: android service notifications

我正在尝试编写MediaPlayer附带的服务。我有不同的活动访问它,所以我认为最好仔细阅读服务。

到目前为止工作正常,我还添加了对startForeground的调用,如here所述。通知出现了。

但是当我现在按下设备上的主页或后退按钮时,服务停止并调用onDestroy,通知图标消失。当我回来时,服务似乎重新绑定了。

我停止了onDestroy上的音乐播放,所以它当然会停止。但即使用户在另一个应用程序上,我也希望保持通知和服务的有效性。

编辑:我希望这是相关部分:

public class MediaPlayerService extends Service {
    private static class PlayerMessageHandler extends Handler {
        private final MediaPlayerService owner;

        public PlayerMessageHandler(MediaPlayerService owner) {
            this.owner = owner;
        }

        @Override
        public void handleMessage(Message msg) {
            // Handle
        }
    }

    private static final int NOTIFICATION_ID = 13138;

    private final Messenger messenger = new Messenger(new PlayerMessageHandler(
            this));
    private MediaPlayer player;
    private Notification notification;

    @Override
    public IBinder onBind(Intent intent) {
        startNotification();
        return messenger.getBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();

        Log.v(TAG, "Media player service created.");

        player = new AudiobookPlayer(this);
        new Thread(seekerUpdate).start();
        isRunning = true;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v(TAG, "Received start id " + startId + ": " + intent);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "Media player service destroyed.");

        if (player.isPlaying()) {
            player.pause();
        }
        sendMessageToUI(MSG_PLAYER_HAS_PAUSED);

        isRunning = false;
    }

    private void sendMessageToUI(int msg) {
        Log.v(TAG, "Sending " + msg);

        sendMessage(Message.obtain(null, msg));
    }

    private void sendMessage(final Message message) {
        // Send
    }

    private void startNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(
                this);
        builder.setSmallIcon(R.drawable.notification);
        builder.setContentTitle(getString(R.string.app_name));
        notification = builder.build();

        startForeground(NOTIFICATION_ID, notification);
    }
}

EDIT2 :活动中的方法取自here

    @Override
protected void onStart() {
    super.onStart();
    // Bind to the service
    bindService(new Intent(this, MediaPlayerService.class),
            playerServiceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (bound) {
        unbindService(playerServiceConnection);
        bound = false;
    }
}

2 个答案:

答案 0 :(得分:4)

您应该提供服务sticky。事实上,这就是tutorial uses

public class HelloService extends Service {
...

 @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      ...

      // If we get killed, after returning from here, restart
      return START_STICKY;
  }
...
}

编辑:从此后的讨论中发现,我的怀疑是正确的,雨果提供了一个现场诊断。我想您现在需要在builder.setOngoing(true);中添加startNotification()

答案 1 :(得分:4)

摘自http://developer.android.com/guide/components/services.html 约束

  

当应用程序组件通过它绑定时,服务被“绑定”   调用bindService()。绑定服务提供客户端 - 服务器   允许组件与服务交互的接口,发送   请求,获取结果,甚至跨进程使用   进程间通信(IPC)。绑定服务只运行   另一个应用程序组件绑定到它。 多个组件可以   立即绑定到服务,但当所有这些服务解除绑定时,服务   被毁了。

您正在onStart绑定您的活动,并在onStop上取消绑定。当您按Home或Back时,您的上一个前景活动可能会调用onStop,从服务中取消绑定最后一个活动并将其删除。

另一种解决方案是调用startService,以便调用onStartCommand,然后调用bindService来绑定活动。