报错log如下
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: java.lang.RuntimeException: Unable to start receiver com.android.music.MediaButtonIntentReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.android.music.musicservicecommand cmp=com.android.music/.MediaPlaybackService (has extras) }: app is in background uid UidRecord{9ec86b u0a86 RCVR idle change:uncached procs:1 seq(0,0,0)}
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ActivityThread.handleReceiver(ActivityThread.java:3221)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ActivityThread.-wrap17(Unknown Source:0)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6523)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.android.music.musicservicecommand cmp=com.android.music/.MediaPlaybackService (has extras) }: app is in background uid UidRecord{9ec86b u0a86 RCVR idle change:uncached procs:1 seq(0,0,0)}
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1522)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ContextImpl.startServiceAsUser(ContextImpl.java:1495)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.content.ContextWrapper.startServiceAsUser(ContextWrapper.java:666)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.content.ContextWrapper.startServiceAsUser(ContextWrapper.java:666)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at com.android.music.MediaButtonIntentReceiver.onReceive(MediaButtonIntentReceiver.java:209)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: at android.app.ActivityThread.handleReceiver(ActivityThread.java:3214)
04-16 15:48:35.662087 29891 29891 E AndroidRuntime: ... 8 more
网上解决方案
Android 8.0 不再允许后台service直接通过startService方式去启动, 具体行为变更如下:
如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。 新的 Context.startForegroundService() 函数将启动一个前台服务。现在,即使应用在后台运行, 系统也允许其调用 Context.startForegroundService()。不过,应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。
我们则需要 context.startService()
替换为context.startForegroundService();
代码如下
Intent i = new Intent(context, MediaPlaybackService.class);
// breeze begin
//context.startServiceAsUser(i, UserHandle.CURRENT);
context.startForegroundServiceAsUser(i, UserHandle.CURRENT);
// breeze end
在MediaPlaybackService
的onCreate()
方法 设置为前台进程
@Override
public void onCreate() {
super.onCreate();
MusicLogUtils.v(TAG, ">> onCreate");
//wangyannan begin
Notification status = new Notification.Builder(MediaPlaybackService.this,
MusicBrowserActivity.MUSIC_NOTIFICATION_CHANNEL).build();
startForeground(PLAYBACKSERVICE_STATUS, status);
//wangyannan end
}
此时会报
Faild to post notification on channel ...
该原因是Android8.0对Notification的要求,要求每一条通知都需要具体的channel
最终解决方案
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// notification id
final String channelId = MusicBrowserActivity.MUSIC_NOTIFICATION_CHANNEL;
// create notification channel
NotificationChannel mChannel = new NotificationChannel(channelId, "MUSIC", NotificationManager.IMPORTANCE_LOW);
mNotificationManager.createNotificationChannel(mChannel);
// set channel id
Notification status = new Notification.Builder(MediaPlaybackService.this).setChannelId(channelId).build();
// start for foreground process
startForeground(PLAYBACKSERVICE_STATUS, status);
问题解决!!!