不允许启动服务意向-安卓奥利奥



我目前正在使用startWakefulService函数,该函数在奥利奥中崩溃。我意识到我要么切换到startForegroundService((并使用前台服务,要么切换到JobIntentService,但根据下面的代码,我不知道该怎么办。(对不起,我是一个android新手(。任何正确方向的观点都将不胜感激。

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GCMIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}

这是我在安卓8.x 上运行时遇到的当前错误

致命异常:java.lang.RuntimeException无法启动接收器com.heyjude.heyjudeapp.gcm.GcmBroadcastReceiver:java.lang.IllegalStateException:不允许启动服务Intent

我也有同样的行为。

为什么会出现此问题

由于Android 8的新后台执行限制,您应该不启动服务后台。

我是如何修复的

将您的GCMIntetService迁移到JobIntentService,而不是IntentService

请按照以下步骤操作:1( 将BIND_JOB_SERVICE权限添加到您的服务:

<service android:name=".service.GCMIntentService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"/>

2( 在GCMIntentService中,使用android.support.v4.app.JobIntentService并重写onHandleWork,而不是扩展IntentService然后删除onHandleIntent中的override

public class GCMIntentService extends JobIntentService {
// Service unique ID
static final int SERVICE_JOB_ID = 50;
// Enqueuing work in to this service.
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, GCMIntentService.class, SERVICE_JOB_ID, work);
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
onHandleIntent(intent);
}
private void onHandleIntent(Intent intent) {
//Handling of notification goes here
}
}

最后,在GCMBroadcastReceiver中,将GCMIntentService排队。

public class GCMBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
// startWakefulService(context, (intent.setComponent(comp)));
//setResultCode(Activity.RESULT_OK);
GCMIntentService.enqueueWork(context, (intent.setComponent(comp)));
}
}

在我们将目标sdk更新为27之后,这个实现对我来说是有效的,我希望它对你有效。

基于文档:

从Android O开始,背景检查限制使此类没有通常更有用。(启动服务通常不安全从收到广播开始,因为你没有任何保证您的应用程序此时处于前台,因此可以这样做。(相反,开发人员应该使用android.app.job.JobScheduler安排作业,这不需要应用程序进行唤醒执行此操作时锁定(系统将负责保持唤醒锁定工作(。

唯一的选择是启动ForeGroundService或使用JobScheduler/JobIntentService

您可以按如下方式启动前台服务:

@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GCMIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
ContextCompat.startForegroundService(context,intent.setComponent(comp));
...
}

您还需要从Service类调用startService()并显示通知。您可以按照我关于这个SO的回答了解实现细节。

相关内容

最新更新