'Fatal Android 12: Exception: startForegroundService() not allowed due to mAllowStartForeground false
I noticed one exception (Firebase Crashlytics) for Pixel 5 and Pixel 4a (both on Android 12), no other devices, happened only two times, one time for each device.
What does it mean? Android 11 and 12 have the same rules for working with foreground services, but there are no issues with Android 11. Is this a bug of Pixel?
From 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)
Solution 1:[1]
Apps that target Android 12 (API level 31) or higher can't start foreground services while running in the background, except for a few special cases. If an app tries to start a foreground service while the app is running in the background, and the foreground service doesn't satisfy one of the exceptional cases, the system throws a ForegroundServiceStartNotAllowedException.
Exemptions from background start restrictions
In the following situations, your app can start foreground services even while your app is running in the background:
- Your app transitions from a user-visible state, such as an activity.
- Your app can start an activity from the background, except for the case where the app has an activity in the back stack of an existing task.
- Your app receives a high-priority message using Firebase Cloud Messaging.
- The user performs an action on a UI element related to your app. For example, they might interact with a bubble, notification, widget, or activity.
- Your app invokes an exact alarm to complete an action that the user requests.
- Your app is the device's current input method.
- Your app receives an event that's related to geofencing or activity recognition transition.
- After the device reboots and receives the ACTION_BOOT_COMPLETED, ACTION_LOCKED_BOOT_COMPLETED, or ACTION_MY_PACKAGE_REPLACED intent action in a broadcast receiver.
Solution 2:[2]
Previously we were using Service
to run background tasks such as backup of data, setting up reminder notifications etc. And the code for invoking the service earlier will be as follows
Intent serviceIntent = new Intent ( context, BackupService.class );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService ( serviceIntent );
} else {
context.startService ( serviceIntent );
}
But, due to Android 12 - Foreground service launch restrictions
, we will not be able to invoke Service for performing background tasks. To learn more about this restriction, please refer to Android 12 Behavior Changes.
So from now on, (i.e) from targetSdk 31 / Android 12+, Service
can be invoked only when the application is in the foreground. When the application is closed or when the application went to the background, invoking Service
using startForegroundService
will cause ForegroundServiceStartNotAllowedException
. So to perform background tasks in Android 12 and above, we need to use Worker
instead of Service
. To learn more about Worker
, please refer to Work Requests.
So for applications targeting SDK 31 / Android 12+, the code for invoking the background task will be as follows,
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 );
}
Sample code for BackupService
(Existing).
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 );
}
}
Sample code for BackupWorker
(Newly added).
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 ();
}
}
Make sure to add the following dependencies in the module-level gradle
file
implementation 'androidx.work:work-runtime:2.7.1'
implementation 'com.google.guava:guava:27.0.1-android'
I have tested the above code working with Android 5, Android 8, Android 11 & Android 12. Working as expected in my case.
Hope this solution helps someone who is targeting their application for SDK 31 / Android 12+.
Solution 3:[3]
To fix this issue in android 12 or higher update your app's logic:
If you discover that your app starts foreground services while running from the background, update your app's logic to use WorkManager. To view an example of how to update your app, look through the WorkManagerSample on GitHub.
Solution 4:[4]
In my case, we use a service that does SIP communications (VoIP), and we are starting a foreground service to do time sensitive operations (such as registration) or when running SIP calls. These tasks cannot be run in a Worker
.
To handle this use case, Android allows you to declare your service's "foregroundServiceType
", and some types are allowed to create foreground services from the background. The other notable use case that this make sense for is media playing.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Himanshi Thakur |
Solution 2 | niranj1997 |
Solution 3 | Shailendra Madda |
Solution 4 | Guss |