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)
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)