天天看点

Android 8.0:java.lang.IllegalStateException:不允许启动服务意图

本文翻译自:Android 8.0: java.lang.IllegalStateException: Not allowed to start service Intent

On application launch, app starts the service that should to do some network task.

在启动应用程序时,应用程序启动应执行某些网络任务的服务。

After targeting API level 26, my application fails to start service on Android 8.0 on background.

定位到API级别26后,我的应用程序无法在后台在Android 8.0上启动服务。
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=my.app.tt/com.my.service }: app is in background uid UidRecord{90372b1 u0a136 CEM idle procs:1 seq(0,0,0)} 引起原因:java.lang.IllegalStateException:不允许启动服务意图{cmp = my.app.tt / com.my.service}:应用程序在后台uid UidRecord {90372b1 u0a136 CEM空闲过程:1 seq(0,0 ,0)}

as I understand it related to: Background execution limits

据我了解,它涉及: 后台执行限制
The startService() method now throws an IllegalStateException if an app targeting Android 8.0 tries to use that method in a situation when it isn't permitted to create background services. 如果针对Android 8.0的应用尝试在不允许创建后台服务的情况下尝试使用该方法,则startService()方法现在将引发IllegalStateException。

" in a situation when it isn't permitted " - what it's actually mean??

“ 在不允许的情况下 ”-实际上是什么意思?

And how to fix it.

以及如何解决。

I don't want to set my service as "foreground"

我不想将服务设置为“前台”

#1楼

参考:https://stackoom.com/question/38sXB/Android-java-lang-IllegalStateException-不允许启动服务意图

#2楼

The permitted situations are a temporary whitelist where the background service behaves the same as before Android O.

允许的情况是一个临时白名单,其中后台服务的行为与Android O之前的行为相同。
Under certain circumstances, a background app is placed on a temporary whitelist for several minutes. 在某些情况下,后台应用会被放置在临时白名单中几分钟。 While an app is on the whitelist, it can launch services without limitation, and its background services are permitted to run. 当应用程序进入白名单时,它可以不受限制地启动服务,并且其后台服务被允许运行。 An app is placed on the whitelist when it handles a task that's visible to the user, such as: 当应用处理用户可见的任务时,该应用将被列入白名单,例如:
  • Handling a high-priority Firebase Cloud Messaging (FCM) message. 处理高优先级的Firebase云消息(FCM)消息。
  • Receiving a broadcast, such as an SMS/MMS message. 接收广播,例如SMS / MMS消息。
  • Executing a PendingIntent from a notification. 从通知中执行PendingIntent。
  • Starting a VpnService before the VPN app promotes itself to the foreground. 在VPN应用提升自身为前台之前启动VpnService。

Source: https://developer.android.com/about/versions/oreo/background.html

资料来源: https : //developer.android.com/about/versions/oreo/background.html

So in other words if your background service does not meet the whitelist requirements you have to use the new JobScheduler .

因此,换句话说,如果您的后台服务不满足白名单要求,则必须使用新的JobScheduler 。

It's basically the same as a background service, but it gets called periodically instead of running in the background continuously.

它与后台服务基本相同,但是它会定期调用,而不是在后台连续运行。

If you're using an IntentService, you can change to a JobIntentService.

如果您使用的是IntentService,则可以更改为JobIntentService。

See @kosev's answer below .

请参阅下面的 @kosev 答案 。

#3楼

if you have integrated firebase messaging push notification then,

如果您集成了Firebase消息传递推送通知,

Add new/update firebase messaging dependencies for android O (Android 8.0), due to Background Execution Limits .

由于后台执行限制 ,为android O(Android 8.0)添加了新的/更新的Firebase消息传递依赖项。
compile 'com.google.firebase:firebase-messaging:11.4.0'
           

upgrade google play services and google repositories if needed.

如有必要,升级Google Play服务和Google存储库。

Update:

更新:
compile 'com.google.firebase:firebase-messaging:11.4.2'
           

#4楼

I got solution.

我有解决办法。

For pre-8.0 devices, you have to just use

startService()

, but for post-7.0 devices, you have to use

startForgroundService()

.

对于8.0之前的设备,您仅需使用

startService()

,而对于7.0以后的设备,则必须使用

startForgroundService()

Here is sample for code to start service.

这是启动服务的代码示例。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(new Intent(context, ServedService.class));
    } else {
        context.startService(new Intent(context, ServedService.class));
    }
           

And in service class, please add the code below for notification:

在服务类别中,请添加以下代码以进行通知:
@Override
public void onCreate() {
    super.onCreate();
    startForeground(1,new Notification());
}
           

Where O is Android version 26.

其中O是Android版本26。

#5楼

If the service is running in a background thread by extending

IntentService

, you can replace

IntentService

with

JobIntentService

which is provided as part of Android Support Library

如果该服务在后台线程通过延长运行

IntentService

,可以取代

IntentService

JobIntentService

其作为Android的支持库的一部分提供

The advantage of using

JobIntentService

is, it behaves as an

IntentService

on pre-O devices and on O and higher, it dispatches it as a job

使用

JobIntentService

的好处是,它在O之前的设备上以及在O和更高

IntentService

上的行为都像

IntentService

一样,将其作为作业分派

JobScheduler

can also be used for periodic/on demand jobs.

JobScheduler

也可以用于定期/按需工作。

But, ensure to handle backward compatibility as

JobScheduler

API is available only from API 21

但是,请确保处理向后兼容性,因为

JobScheduler

API仅可从API 21获得

#6楼

From the firebase release notes , they state that support for Android O was first released in 10.2.1 (although I'd recommend using the most recent version).

从firebase发行说明中 ,他们指出对Android O的支持是在10.2.1中首次发布的(尽管我建议使用最新版本)。

please add new firebase messaging dependencies for android O

请为Android O添加新的Firebase消息传递依赖项
compile 'com.google.firebase:firebase-messaging:11.6.2'
           

upgrade google play services and google repositories if needed.

如有必要,升级Google Play服务和Google存储库。