当前位置: 首页 > 知识库问答 >
问题:

在Android 12(SDK 31)中获取android.app.前台服务启动不允许异常

慕光赫
2023-03-14

我将我的应用程序TaretSdkVersioncompileSdkVersion升级到SDK 31,并开始在后台更新小部件的服务中接收以下应用程序崩溃。

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:4321)
  at android.app.ActivityThread.access$1600 (ActivityThread.java:247)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2068)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at android.app.ActivityThread.main (ActivityThread.java:7842)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003)
Caused by: android.app.ForegroundServiceStartNotAllowedException: 
  at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
  at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
  at android.os.Parcel.readParcelable (Parcel.java:3333)
  at android.os.Parcel.createExceptionOrNull (Parcel.java:2420)
  at android.os.Parcel.createException (Parcel.java:2409)
  at android.os.Parcel.readException (Parcel.java:2392)
  at android.os.Parcel.readException (Parcel.java:2334)
  at android.app.IActivityManager$Stub$Proxy.startService (IActivityManager.java:5971)
  at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1847)
  at android.app.ContextImpl.startForegroundService (ContextImpl.java:1823)
  at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:779)
  at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:779)
  at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onUpdate (WidgetClassName.java:48)
  at android.appwidget.AppWidgetProvider.onReceive (AppWidgetProvider.java:66)
  at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onReceive (WidgetClassName.java)
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:4312)
  at android.app.ActivityThread.access$1600 (ActivityThread.java:247)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2068)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at android.app.ActivityThread.main (ActivityThread.java:7842)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003)
Caused by: android.os.RemoteException: 
  at com.android.server.am.ActiveServices.startServiceLocked (ActiveServices.java:691)
  at com.android.server.am.ActiveServices.startServiceLocked (ActiveServices.java:616)
  at com.android.server.am.ActivityManagerService.startService (ActivityManagerService.java:11839)
  at android.app.IActivityManager$Stub.onTransact (IActivityManager.java:2519)
  at com.android.server.am.ActivityManagerService.onTransact (ActivityManagerService.java:2498)

此外,如果您使用的是Firebase Crashlytics之类的东西,那么stacktrace必须是这样的-

Caused by android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service com.mypackage.appname/.ui.widget.widget_package.MyForegroundServiceName
       at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:54)
       at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:50)
       at android.os.Parcel.readParcelable(Parcel.java:3333)
       at android.os.Parcel.createExceptionOrNull(Parcel.java:2420)
       at android.os.Parcel.createException(Parcel.java:2409)
       at android.os.Parcel.readException(Parcel.java:2392)
       at android.os.Parcel.readException(Parcel.java:2334)
       at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:5971)
       at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1847)
       at android.app.ContextImpl.startForegroundService(ContextImpl.java:1823)
       at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
       at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
       at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onUpdate(WidgetClassName.java:48)
       at android.appwidget.AppWidgetProvider.onReceive(AppWidgetProvider.java:66)
       at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onReceive(WidgetClassName.java)
       at android.app.ActivityThread.handleReceiver(ActivityThread.java:4312)
       at android.app.ActivityThread.access$1600(ActivityThread.java:247)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2068)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7842)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

我正在添加重现此问题的方法,并修复了此问题,因为当我搜索StackOverflow时,我没有在StackOverflow上找到任何关于此问题的留档。

共有3个答案

师曦
2023-03-14

在创建通知和NotificationManager.IMPORTANCE_MAX时使用

赫连昕
2023-03-14

如果您的应用程序是MediaPlayer(即使用MediaBrowseService),并且您遇到了ForegroundServiceStartNotAllowedException崩溃,那么您可能需要:

>

包括服务信息。在调用服务时,前台\u SERVICE\u TYPE\u MEDIA\u PLAYBACK参数。启动地面方法

司马同
2023-03-14

第1步。将您的targetSdkVersion和compileSdkVersion更新到SDK 31。

第2步。当你的应用程序在后台时,尝试运行任何前台服务。在我的例子中,是在updatePeriodMillis之后调用小部件的onUpdate方法,该方法将启动前台服务,通过从internet获取适当的信息来更新数据。

记住:Android 8.0中添加的后台执行限制与此问题无关。这个限制/例外是在Android 12/SDK 31-Source中添加的。

针对Android 12(API级别31)或更高版本的应用程序在后台运行时无法启动前台服务,只有少数特殊情况除外。如果应用程序在后台运行时尝试启动前台服务,而前台服务不满足其中一种例外情况,系统将抛出ForegroundServiceStartNotAllowedException。

这些特殊情况包括:

>

您的应用程序可以从后台启动活动,但应用程序在现有任务的后台堆栈中有活动的情况除外。

您的应用程序使用Firebase云消息接收高优先级消息。

用户对与应用程序相关的UI元素执行操作。例如,它们可能与气泡、通知、小部件或活动进行交互。

你的应用程序调用一个精确的警报来完成用户请求的操作。

你的应用程序是设备的当前输入法。

您的应用程序接收到与地理Geofence或活动识别转换相关的事件。

设备重新启动并接收到ACTION\u BOOT\u COMPLETED、ACTION\u LOCKED\u BOOT\u COMPLETED或ACTION\u MY\u PACKAGE\u替换广播接收器中的intent ACTION后。

您的应用程序在广播接收器中接收ACTION\u TIMEZONE\u CHANGED、ACTION\u TIME\u CHANGED或ACTION\u LOCALE\u CHANGED intent操作。

您的应用接收到需要Bluetooth\u连接或Bluetooth\u扫描权限的Bluetooth广播。

具有某些系统角色或权限的应用程序,例如设备所有者和配置文件所有者。

您的应用程序使用Companion Device Manager并声明REQUEST\u Companion\u START\u FOREGROUND\u SERVICES\u FROM\u BACKGROUND权限或REQUEST\u Companion\u RUN\u IN\u BACKGROUND权限。尽可能使用REQUEST\u COMPANION\u START\u FOREGROUND\u SERVICES\u FROM\u BACKGROUND。

用户关闭应用的电池优化。您可以通过在系统设置中将用户发送到应用的应用信息页面来帮助用户找到此选项。为此,请调用包含ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS意图操作的意图。

这将在Play Store中持续一段时间,直到Google强制升级到API级别31。

目前,从2021 11月开始,所有应用程序必须以API级别30及以上为目标。因此,如果您的应用程序使用API Level 31,请降级您的CompileSDK版本

如果您使用前台服务来执行对时间敏感的工作,请在精确的警报内启动前台服务。请在此处留档查看有关此的更多信息-

这就是我最终用于我的应用程序的解决方案。使用WorkManager计划并开始后台工作。从此处的文档中查看有关此的更多信息-

您可以在此处了解有关WorkManager的更多信息-

WorkManager示例的Github Repo-

我特别添加了这个答案,因为搜索这个异常并不会带来任何资源来了解为什么服务在Android 12上表现不同。所有这些都存在于谷歌的文档中,并且始终记得检查文档中的行为变化。

与此更改相关的所有内容都可以在此处找到-

 类似资料:
  • 在调用(和)之后,我的应用程序怎么可能就在后台呢? 这对我来说没有任何意义。这可能是平台错误吗?受这次崩溃影响的所有3500+用户都在Android P上。

  • 问题内容: 我目前正在使用在Oreo中崩溃的startWakefulService函数。我意识到我要么必须切换到startForegroundService()并使用前台服务,要么切换到JobIntentService,但是基于下面的代码,我不确定该怎么做。(对不起,我是android新手)。正确方向的任何观点将不胜感激。 这是在Android 8.x上运行时遇到的当前错误 致命异常:java.l

  • 这是在Android8.x上运行时出现的当前错误 致命异常:java.lang.RuntimeException无法启动接收方com.heyjude.heyjudeapp.gcm.gcmbroadcastreceiver:java.lang.illegalstateException:不允许启动服务意图{act=com.google.android.c2dm.Intent.receive flg=

  • 我创建了一个跟踪设备移动位置的服务。服务由绑定到它的活动启动,在该活动中有一个“开始跟踪”按钮。当按下这个按钮时,我需要服务在前台启动,这样它就可以存储设备移动到的位置,即使与它绑定的活动已经关闭,或者应用程序被最小化。 以下是我的服务:

  • 那是什么? 无法获取主令牌java。lang.SecurityException:未经com许可,不允许启动服务意图{act=com.google.android.c2dm.Intent.REGISTER pkg=com.google.android.gms(has extras)}。谷歌。Androidc2dm。准许在android上接收。应用程序。ContextImpl。android上的st

  • 我有一个jquery脚本(从github下载),可以删除实体。下面是脚本。 }); 而我就是这样利用它的 相应的laravel路线如下所示 然而,当我尝试按下X(删除按钮)时,我得到了405方法不允许的错误。错误如下 这在我的本地沙箱上运行良好。 任何帮助都将不胜感激。 谢啦