最终我想在我的应用程序死后运行以下代码:
playerNotificationManager.setPlayer(null);
我已经看到很多问题,询问如何使服务保持活动状态,但是我希望服务停止运行,并且一直在后台徘徊。
我有一个使用ExoPlayer的应用程序,该服务具有在您最小化该应用程序时继续在后台播放音频的功能。该服务基本上看起来像这样:
PlayerService.java :
package com.blueframetech.bfsdk.adapters;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import com.blueframetech.bfsdk.R;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
public class PlayerService extends Service
{
public Player player;
private PlayerNotificationManager playerNotificationManager;
public void onCreate()
{
super.onCreate();
final Context context = this;
playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
context, "Channel ID", R.string.app_name, 0,
new PlayerNotificationManager.MediaDescriptionAdapter() {
@Override
public String getCurrentContentTitle ( Player player )
{
return null;
}
@Nullable
@Override
public PendingIntent createCurrentContentIntent ( Player player )
{
return null;
}
@Nullable
@Override
public String getCurrentContentText ( Player player )
{
return null;
}
@Nullable
@Override
public Bitmap getCurrentLargeIcon (
Player player, PlayerNotificationManager.BitmapCallback callback
)
{
return null;
}
}
);
playerNotificationManager.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
@Override
public void onNotificationStarted ( int notificationId, Notification notification )
{
startForeground(0, notification);
}
@Override
public void onNotificationCancelled ( int notificationId )
{
stopSelf();
}
});
}
private final IPlayerInterface.Stub mBinder = new IPlayerInterface.Stub() {
public void setPlayer ( int playerId ) throws RemoteException
{
if (playerId < 0)
{
playerNotificationManager.setPlayer(null);
}
else
{
player = ExoPlayerSingleton.getInstance(playerId);
playerNotificationManager.setPlayer(player);
}
}
};
@Override
public IBinder onBind ( Intent intent )
{
return mBinder;
}
}
要启动该服务,请执行以下操作:
PlayerActivity.java :
playerId = ExoPlayerSingleton.createInstance();
playerView = findViewById(R.id.player_view);
serviceConnection = new ServiceConnection()
{
@Override
public void onServiceConnected ( ComponentName name, IBinder service )
{
playerService = (IPlayerInterface) service;
}
@Override
public void onServiceDisconnected ( ComponentName name )
{
playerService = null;
}
};
context.bindService(
new Intent(getContext(), PlayerService.class),
serviceConnection,
Context.BIND_AUTO_CREATE
);
然后,在活动的onDestroy
方法中,我添加了以下内容以避免在按下后退按钮时泄漏服务:
getContext().unbindService(serviceConnection);
我还有一个AIDL文件以及onPause
和onResume
中的一些代码,可以在PlayerView
和PlayerService
之间进行切换(此切换绑定到ExoPlayer实例) -一切似乎都按预期进行:
playerView.setPlayer(null);
playerService.setPlayer(playerId);
// ...
playerService.setPlayer(null);
playerView.setPlayer(ExoPlayerSingleton.getInstance(playerId));
如果我最小化应用程序,则该服务将接管回放,出现通知,然后我继续听音频。但是,如果我随后转到任务管理器并终止我的应用程序,则音频将中断。 很好。问题是在音频中断后,通知仍保持打开状态,并且该服务仍在后台运行,什么也不做。这是因为以这种方式杀死应用程序后,我的活动的onDestroy
方法无法运行。
进入这种状态后,只有两种方法可以终止通知:
当我的应用程序死机时,如何通知我的服务死机?我不喜欢这个僵尸通知。