欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android8.0 java.lang.IllegalStateException: Not allowed to start service Intent app is in background

程序员文章站 2023-11-07 19:39:52
报错log如下 04-16 15:48:35.662087 29891 29891 e androidruntime: java.lang.runtimeexception: unable to...

报错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);

问题解决!!!