首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Android12中获取android.app.ForegroundServiceStartNotAllowedException (SDK 31)

在Android12中获取android.app.ForegroundServiceStartNotAllowedException (SDK 31)
EN

Stack Overflow用户
提问于 2021-10-17 13:49:28
回答 3查看 8.9K关注 0票数 27

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

代码语言:javascript
运行
复制
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之类的东西,那么您的堆栈跟踪必须类似于这个->

代码语言:javascript
运行
复制
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上搜索时没有找到任何关于这个问题的文档。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-17 13:49:28

如何再现坠机

步骤1.将targetSdkVersioncompileSdkVersion更新为SDK 31。

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

记住:在Android8.0中添加的后台执行限制与此问题无关。这个限制/异常是在Android12/SDK 31 - 来源中添加的。

这是什么例外,为什么会增加呢?

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

这些特例是:

  • 您的应用程序从用户可见状态(如活动)过渡。
  • 您的应用程序可以从后台启动一个活动,除了应用程序在现有任务的后台堆栈中有一个活动的情况。
  • 您的应用程序使用Firebase消息接收高优先级消息。
  • 用户对与应用程序相关的UI元素执行操作。例如,它们可能与气泡、通知、小部件或活动交互。
  • 您的应用程序调用一个精确的警报来完成用户请求的操作。
  • 您的应用程序是设备当前的输入方法。
  • 您的应用程序接收到与地理位置或活动识别转换相关的事件。
  • 在设备重新启动并接收广播接收器中的ACTION_BOOT_COMPLETED、ACTION_LOCKED_BOOT_COMPLETED或ACTION_MY_PACKAGE_REPLACED意图操作后。
  • 您的应用程序在广播接收器中接收ACTION_TIMEZONE_CHANGED、ACTION_TIME_CHANGED或ACTION_LOCALE_CHANGED意图操作。
  • 您的应用程序接收需要BLUETOOTH_CONNECT或BLUETOOTH_SCAN权限的蓝牙广播。
  • 具有特定系统角色或权限的应用程序,如设备所有者和配置文件所有者。
  • 您的应用程序使用Companion设备管理器并声明REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND权限或REQUEST_COMPANION_RUN_IN_BACKGROUND权限。只要有可能,就使用REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND.
  • 用户关闭您的应用程序的电池优化。通过在系统设置中将用户发送到应用程序的App页面,您可以帮助用户找到这个选项。为此,调用包含ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS意图操作的意图。

可能的解决办法

解决方案1

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

目前,从2021年11月开始,所有应用程序都必须针对30级以上的API。因此,如果您在应用程序中使用API 31,那么将compileSdkVersion & targetSdkVersion降级到API 30应该可以解决这个问题(至少有一段时间)。

解决方案2

对时间敏感的工作

如果您使用前台服务来执行时间敏感的工作,请在精确警报范围内启动前台服务。从这里的-> 设置精确的警报文档中查看更多关于这一点的信息。

对时间不敏感/快速工作

这是我最后在应用程序中使用的解决方案。使用WorkManager来安排和启动后台工作。从这里的-> 加快工作进度文档中查看更多关于这一点的信息。

您可以在这里更多地了解WorkManager,->,WorkManager

WorkManager样品-> WorkManager样本的Github回购

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

与此更改相关的所有内容都可以在-> Android 12行为改变中找到,特别是在前台服务启动限制中。

票数 28
EN

Stack Overflow用户

发布于 2021-12-16 11:57:23

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

  1. 更新您的声明,以指定您的服务用于使用android:foregroundServiceType="mediaPlayback"Service声明中播放媒体
  2. 在调用ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK方法时包括Serivce.startForeground参数
票数 10
EN

Stack Overflow用户

发布于 2022-04-12 08:48:36

使用.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)创建通知并创建NotificationManager.IMPORTANCE_MAX

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69604951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档