【问题标题】:Not allowed to start service Intent - Android Oreo不允许启动服务 Intent - Android Oreo
【发布时间】:2018-12-23 12:13:42
【问题描述】:

我目前正在使用在 Oreo 中崩溃的 startWakefulService 函数。我意识到我要么必须切换到 startForegroundService() 并使用前台服务,要么切换到 JobIntentService 但根据我下面的代码,我不确定该怎么做。 (对不起,我是一个安卓新手)。任何正确方向的观点将不胜感激。

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);
}
}

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

致命异常:java.lang.RuntimeException 无法启动接收器 com.heyjude.heyjudeapp.gcm.GcmBroadcastReceiver:java.lang.IllegalStateException:不允许启动服务 Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x1000010 pkg=com.app.app cmp=com.app.app/.gcm.GCMIntentService (has extras) }: 应用在后台 uid UidRecord{f602fba u0a114 RCVR idle procs:1 seq(0,0,0)}

【问题讨论】:

    标签: java android android-8.0-oreo


    【解决方案1】:

    基于documentation

    从 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));
        ...
    }
    

    您还需要从您的服务类调用startService() 并显示通知。您可以在SO 上关注我的回答,了解实施细节。

    【讨论】:

      【解决方案2】:

      我遇到了同样的行为。

      为什么会出现这个问题?

      由于 Android 8 的新 Background Execution Limits,您应该 不启动服务后台。

      我是如何解决的

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

      请按以下步骤操作: 1) 为您的服务添加 BIND_JOB_SERVICE 权限:

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

      2) 在您的 GCMIntentService 中,改为扩展 IntentService,使用 android.support.v4.app.JobIntentService 并覆盖 onHandleWork 然后删除你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 后,这个实现对我有用,我希望它对你有用。

      【讨论】:

      • WakefulBroadcastReceiver 已弃用?
      • @DylanBurton 由于背景检查限制,当您支持 Android Oreo 时它不再有用。
      • 如何使用警报管理器来完成(尝试安排警报)
      猜你喜欢
      • 2018-03-08
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      相关资源
      最近更新 更多