我正在尝试编写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;
}
}
答案 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
来绑定活动。