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

致命的Android 12:异常:由于mAllowStartForeground false,不允许开始前景服务()

邵俊才
2023-03-14

我注意到Pixel 5和Pixel 4a(均在Android 12上)的一个例外(Firebase Crashlytics),没有其他设备,只发生了两次,每个设备一次。

这是什么意思?Android 11和12使用前台服务的规则相同,但Android 11没有问题。这是像素错误吗?

来自Firebase Crashlytics:

Fatal Exception: android.app.ForegroundServiceStartNotAllowedException
startForegroundService() not allowed due to mAllowStartForeground false: service com.helge.droiddashcam/.service.RecorderService

android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
androidx.core.content.ContextCompat.startForegroundService (ContextCompat.java:6)
MyAppPackageHidden.service.RecorderService$Companion.startService (RecorderService.java:2)
MyAppPackageHidden.ui.rec.RecActivity$getConnectionRecorderService$1.onServiceConnected (RecActivity.java:4)
android.app.LoadedApk$ServiceDispatcher.doConnected (LoadedApk.java:2077)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003)

Fatal Exception: android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service MyAppPackageHidden/.service.RecorderService
       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 androidx.core.content.ContextCompat$Api26Impl.startForegroundService(ContextCompat.java)
       at androidx.core.content.ContextCompat.startForegroundService(ContextCompat.java:6)
       at MyAppPackageHidden.service.RecorderService$Companion.startService(RecorderService.java:2)
       at MyAppPackageHidden.ui.rec.RecActivity$getConnectionRecorderService$1.onServiceConnected(RecActivity.java:4)
       at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:2077)
       at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:2110)
       at android.os.Handler.handleCallback(Handler.java:938)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7838)
       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)

Caused by android.os.RemoteException: Remote stack trace:
    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)

共有3个答案

乜嘉悦
2023-03-14

在我的例子中,我们使用一个进行SIP通信(VoIP)的服务,并且我们正在启动一个前台服务来执行时间敏感的操作(例如注册)或在运行SIP调用时。这些任务不能在工作线程中运行。

为了处理这个用例,Android允许您声明服务的“foregroundServiceType”,并且允许某些类型从后台创建前台服务。另一个值得注意的用例是媒体播放。

史英飙
2023-03-14

以前我们使用Service来运行后台任务,例如数据备份、设置提醒通知等。之前调用服务的代码如下

Intent serviceIntent = new Intent ( context, BackupService.class );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService ( serviceIntent );
} else {
    context.startService ( serviceIntent );
}

但是,由于Android 12-前台服务启动限制,我们将无法调用服务来执行后台任务。要了解有关此限制的更多信息,请参阅Android 12行为更改。

因此,从现在起,(即)从targetSdk 31/Android 12开始,只有当应用程序位于前台时,才能调用服务。当应用程序关闭或应用程序转到后台时,使用启动Foregroundservice调用服务将导致ForegroundServiceStartNotAllowedException。因此,要在Android 12及更高版本中执行后台任务,我们需要使用工作者,而不是服务。要了解有关工人的更多信息,请参阅工作请求。

因此,对于以SDK 31/Android 12为目标的应用程序,调用后台任务的代码如下:,

Intent serviceIntent = new Intent ( context, BackupService.class );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    OneTimeWorkRequest request = new OneTimeWorkRequest.Builder ( BackupWorker.class ).addTag ( "BACKUP_WORKER_TAG" ).build ();
    WorkManager.getInstance ( context ).enqueue ( request );
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService ( serviceIntent );
} else {
    context.startService ( serviceIntent );
}

备份服务的示例代码(现有)。

public class BackupService extends Service {

    private static final String TAG = "BackupService";

    @Nullable
    @Override
    public IBinder onBind ( Intent intent ) {
        return null;
    }

    @Override
    public int onStartCommand ( Intent intent, int flags, int startId ) {
        Log.d ( TAG, "onStartCommand" );
        startForeground ( BACKUP_SERVICE_NOTIFICATION_ID, createServiceNotification () );
        //call methods to perform background task
        return super.onStartCommand ( intent, flags, startId );
    }
}

BackupWorker的示例代码(新增)。

public class BackupWorker extends Worker {

    private static final String TAG = "BackupWorker";

    public BackupWorker ( @NonNull Context context, @NonNull WorkerParameters workerParams ) {
        super ( context, workerParams );
    }

    @NonNull
    @Override
    public Result doWork () {
        //call methods to perform background task
        return Result.success ();
    }
}

确保在模块级gradle文件中添加以下依赖项

implementation 'androidx.work:work-runtime:2.7.1'
implementation 'com.google.guava:guava:27.0.1-android'

我已经用Android 5、Android 8、Android 11测试了上述代码

希望此html" target="_blank">解决方案能够帮助那些针对SDK 31/Android 12的应用程序的用户。

邢雨华
2023-03-14

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

背景启动限制豁免

在以下情况下,即使您的应用在后台运行,您的应用也可以启动前台服务:

  • 您的应用程序从用户可见状态转换,例如活动。
  • 您的应用程序可以从后台启动活动,除非应用程序在现有任务的后栈中有活动。
  • 您的应用使用Firebase Cloud Messaging接收高优先级消息。
  • 用户对与您的应用相关的UI元素执行操作。例如,他们可能会与气泡、通知、小部件或活动进行交互。
  • 您的应用程序会调用一个精确的警报来完成用户请求的操作。
  • 您的应用程序是设备当前的输入法。
  • 您的应用程序会收到与地理Geofence或活动识别转换相关的事件。
  • 设备重新启动并在广播接收器中接收到ACTION_BOOT_COMPLETED、ACTION_LOCKED_BOOT_COMPLETED或ACTION_MY_PACKAGE_REPLACED意图操作后。

有关更多信息,请查看link1 link2

 类似资料:
  • 我正在尝试缓存一个网站的站点地图,它是从我正在工作的一个网站的控制器生成的,但显然我做错了什么,因为我不理解错误消息。下面是造成问题的代码片段(它是一个控制器方法)。在添加缓存之前,一切都正常工作。

  • 我在mainActivity(log.d(“create response”,json.toString())的第275行得到一个带有NullPointerException的致命异常我以前引用了该对象为JSONObject json=new JSONObject();我仍然得到空指针。我的原木猫在下面。 日志猫:

  • 我在我的windows 7上运行第一次Kafka,启动Kafka服务时出错 > 我下载了kafka_2.12-2.0.0并在C:\kafka_2.12-2.0.0上解压缩 在C:\kafka_2.12-2.0.0\config\zookeeper.properties将dataDir更改为dataDir=C:/kafka_2.12-2.0.0/data/zooKeer(文件夹dataDir=C:/

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

  • 我将我的应用程序和升级到SDK 31,并开始在后台更新小部件的服务中接收以下应用程序崩溃。 此外,如果您使用的是Firebase Crashlytics之类的东西,那么stacktrace必须是这样的- 我正在添加重现此问题的方法,并修复了此问题,因为当我搜索StackOverflow时,我没有在StackOverflow上找到任何关于此问题的留档。

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