3

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

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

但是当我现在按下设备上的主页或返回按钮时,该服务停止并被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:来自活动的方法,取自这里

    @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;
    }
}
4

2 回答 2

4

摘自http://developer.android.com/guide/components/services.html 绑定

当应用程序组件通过调用 bindService() 绑定到服务时,服务被“绑定”。绑定服务提供了一个客户端-服务器接口,允许组件与服务交互、发送请求、获取结果,甚至通过进程间通信 (IPC) 跨进程执行此操作。绑定服务仅在另一个应用程序组件绑定到它时运行。多个组件可以一次绑定到服务,但是当所有组件都解除绑定时,服务将被销毁。

您正在绑定您的活动onStart并取消绑定onStop。当您按下 Home 或 Back 时,您的最后一个前台 Activity 可能会调用onStop,从服务中解除最后一个 Activity 的绑定并杀死它。

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

于 2013-08-16T14:56:30.263 回答
4

你应该让你的服务有粘性。事实上,这就是教程使用的:

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()

于 2013-08-16T12:09:42.983 回答