Foreground Service crashing on Android 14
Asked Answered
C

4

38

I have an Android application that worked fine until Android 13. After upgrading to Android 14 (Setting targetSdkVersion as 34) my application is Crashing on Android 14. Here's my crash log.

java.lang.RuntimeException: Unable to start service com.example.bleapp.service.BleAppService@1d05078 with Intent { cmp=com.example.bleapp/.service.BleAppService }: java.lang.SecurityException: Starting FGS with type connectedDevice callerApp=ProcessRecord{718b5ad 5016:com.example.bleapp/u0a356} targetSDK=34 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE] any of the permissions allOf=false [android.permission.BLUETOOTH_ADVERTISE, android.permission.BLUETOOTH_CONNECT, android.permission.BLUETOOTH_SCAN, android.permission.CHANGE_NETWORK_STATE, android.permission.CHANGE_WIFI_STATE, android.permission.CHANGE_WIFI_MULTICAST_STATE, android.permission.NFC, android.permission.TRANSMIT_IR, android.permission.UWB_RANGING, USB Device, USB Accessory]
  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4839)
  at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loopOnce(Looper.java:205)
  at android.os.Looper.loop(Looper.java:294)
  at android.app.ActivityThread.main(ActivityThread.java:8177)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.SecurityException: Starting FGS with type connectedDevice callerApp=ProcessRecord{718b5ad 5016:com.example.bleapp/u0a356} targetSDK=34 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE] any of the permissions allOf=false [android.permission.BLUETOOTH_ADVERTISE, android.permission.BLUETOOTH_CONNECT, android.permission.BLUETOOTH_SCAN, android.permission.CHANGE_NETWORK_STATE, android.permission.CHANGE_WIFI_STATE, android.permission.CHANGE_WIFI_MULTICAST_STATE, android.permission.NFC, android.permission.TRANSMIT_IR, android.permission.UWB_RANGING, USB Device, USB Accessory]
  at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
  at android.os.Parcel.createException(Parcel.java:3041)
  at android.os.Parcel.readException(Parcel.java:3024)
  at android.os.Parcel.readException(Parcel.java:2966)
  at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:6761)
  at android.app.Service.startForeground(Service.java:775)
  at com.example.bleapp.service.BleAppService.onStartCommand(BleAppService.kt:28)
  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4821)
  at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loopOnce(Looper.java:205)
  at android.os.Looper.loop(Looper.java:294)
  at android.app.ActivityThread.main(ActivityThread.java:8177)
Coe answered 21/8, 2023 at 8:56 Comment(1)
It comes with another issue. See this LinkLeta
C
49

Starting from Android 14, you need to declare a specific permission for foreground service, depending on the use case you are using Foreground service for. This is a normal level permission and can be granted by simply declaring it in manifest. A list of supported permissions along with uses cases can be found here.

https://developer.android.com/about/versions/14/changes/fgs-types-required#use-cases

Example:

<manifest ...>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
  <application ...>
  <service
      android:name=".MyService"
      android:foregroundServiceType="location"
      android:exported="false">
  </service>
</application>

You also need to add the proper foreground service call at runtime:

Service.startForeground(0, notification, FOREGROUND_SERVICE_TYPE_LOCATION)

Coe answered 21/8, 2023 at 8:56 Comment(7)
Something is slightly misleading in the way Google communicates about API34 changes : these constraints not only apply to Services but also to Workers, if they call setForegroundAsync. In that case, the manifest has to be updated too, by declaring android:name="androidx.work.impl.foreground.SystemForegroundService" Reference : developer.android.com/guide/background/persistent/how-to/…Dwyer
This does not imply that you do not need to request the normal runtime location permission anymore. You still need to set it up and request it in the same way as before since runtime permissions were added.Orourke
@Ajith M A It not fix the issue, my app still crash on Android 14 after following Google guide line.Bowser
@Bowser Were you able to fix it? What was the issue?Coe
@AjithMA it still crash on Samsung, I still not found any solution.Bowser
I found a solution where you first have to check if the coarse and fine location are granted before starting foregroundService. It worker for me and is a nice solution.Fruitage
What's this? "You also need to add the proper foreground service call at runtime: Service.startForeground(0, notification, FOREGROUND_SERVICE_TYPE_LOCATION)"? I use this to run the service: Intent(this, LocationService::class.java).also { intent -> bindService(intent, connection, BIND_AUTO_CREATE) }Montagu
C
4

I solved this problem with my location service. Please note this:

https://developer.android.com/guide/components/foreground-services#fgs-prerequisites

Beginning with Android 14 (API level 34), when you launch a foreground service, the system checks for specific prerequisites based on service type. For example, if you try to launch a foreground service of type location, the system checks to make sure your app already has either the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission. If it doesn't, the system throws SecurityException.
For this reason, you must confirm that the required prerequisites are met before you start a foreground service. The foreground service type documentation lists the required prerequisites for each foreground service type.

I added a check to the code to check the granted permissions before starting the service and the application no longer crashes.

if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
  && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
)
{
  val intent = Intent(context, MyService::class.java)
  context.startForegroundService(intent)
} else {
  Log.e("MyService", "No permissions ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION!")
}

My manifest file:

<manifest ...>
  <uses-feature android:name="android.hardware.location.gps"/>
  <!-- permissions -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
  
  <application ...>
    <service
      android:name=".MyService"
      android:enabled="true"
      android:exported="false"
      android:foregroundServiceType="location"
      android:stopWithTask="false"
    />
  </application>
</manifest>
Cumberland answered 11/12, 2023 at 20:51 Comment(3)
why declaring != PackageManager.PERMISSION_GRANTED , this canbe misleading , shouldn't be like this ? : == PackageManager.PERMISSION_GRANTEDSaleh
@Saleh Yes you are right. I fixed the error in the code.Cumberland
@Cumberland that will work, but how to be with case if user grand permission, start service, go to settings and turn off location permission, and app will crash..(how to avoid the crash), do you know/have any solution?Airspace
T
1
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

try to add the code above in your AndroidManifest.xml.

Timer answered 7/5, 2024 at 9:39 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Exothermic
U
0

In my App, this code was the problem. In Noftication from work manager. I removed this.

 setForegroundAsync(ForegroundInfo(notificationId, builder.build()))

The error would also occurrs because of the wrong notificationID.

Underclothing answered 5/1, 2024 at 7:13 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.