flutter_foreground_task icon indicating copy to clipboard operation
flutter_foreground_task copied to clipboard

On Android 14+, allow for the subset of declared permissions to be specified at the time of launching the service

Open fareesh opened this issue 1 year ago • 0 comments

My use-case is as follows

  • My app has an audio rooms feature
  • (A) Some of my users only listen - they never accept the MICROPHONE permission and use the app as listeners
  • (B) Some of my users speak and listen as well
  • When the app is in the background, the permissions for the foreground task depend on which of the two they are
    • In case of (A) we need to launch the foreground task with a subset of the declared permissions (MEDIA_PLAYBACK)
    • In case of (B) we need to launch the foreground task with all MICROPHONE + MEDIA_PLAYBACK
  • This requires a decision at run-time to determine which permissions to launch with
  • If you launch the service with MICROPHONE permissions but the user has not accepted the MICROPHONE permission, you get a SecurityException (see below)

From the relevant Android docs:

Note: If an app that targets API level 28 or higher attempts to create a foreground service without requesting the FOREGROUND_SERVICE permission, the system throws a SecurityException. Similarly, if an app targets API level 34 or higher and doesn't request the appropriate specific permission, the system throws SecurityException.

and

Inside the service, usually in onStartCommand(), you can request that your service run in the foreground. To do so, call ServiceCompat.startForeground() (available in androidx-core 1.12 and higher). This method takes the following parameters:

  • The service
  • A positive integer that uniquely identifies the notification in the status bar
  • The Notification object itself
  • The foreground service types identifying the work done by the service

These types might be a subset of the types declared in the manifest, depending on the specific use case. Then, if you need to add more service types, you can call startForeground() again.

These changes modify AndroidNotificationOptions to allow the developer to specify the bitmap sum of permissions with which the service will be launched (via ServiceCompat.startForeground as mentioned above). This also adds a class of constants AndroidForegroundServiceType.dart for the user to easily sum up the permissions they need:

e.g.

AndroidNotificationOptions(
   ...
   permissionTypes: AndroidForegroundServiceType.MICROPHONE + AndroidForegroundServiceType.MEDIA_PLAYBACK
)

fareesh avatar Mar 10 '24 00:03 fareesh