tanguyantoine / react-native-music-control

Display and manage media controls on lock screen and notification center for iOS and Android.
https://www.npmjs.com/package/react-native-music-control
MIT License
697 stars 264 forks source link

ForegroundServiceStartNotAllowedException (Android 12) #400

Open rafaelmaeuer opened 2 years ago

rafaelmaeuer commented 2 years ago

Problem: I am getting lots of ForegroundServiceStartNotAllowedException from Devices with Android 12. It seems to happen on NotificationService.forceForeground() in MusicControlNotification.java:215

It might likely relate to Android 12 Foreground Service restrictions (from Android Docs):

Examples of apps that would use foreground services include the following:

A music player app that plays music in a foreground service. The notification might show the current song that is being played.

Possible solution: Add a service entry to AndroidManifest.xml with android:foregroundServiceType = mediaPlayback attribute.

<service
  android:name="com.tanguyantoine.react.MusicControlNotification$NotificationService"
  android:foregroundServiceType="mediaPlayback"
  android:exported="false">
</service>

I cannot verify this fix is working, as I don't have an Android 12 device to test it myself...

Description

  1. Sample code (provide repo url or sample code)
android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service <app-identifier>/com.tanguyantoine.react.MusicControlNotification$NotificationService
    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:3345)
    at android.os.Parcel.createExceptionOrNull(Parcel.java:2432)
    at android.os.Parcel.createException(Parcel.java:2421)
    at android.os.Parcel.readException(Parcel.java:2404)
    at android.os.Parcel.readException(Parcel.java:2346)
    at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:6914)
    at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1926)
    at android.app.ContextImpl.startForegroundService(ContextImpl.java:1892)
    at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:796)
    at androidx.core.content.ContextCompat$Api26Impl.startForegroundService(ContextCompat.java:933)
    at androidx.core.content.ContextCompat.startForegroundService(ContextCompat.java:701)
    at com.tanguyantoine.react.MusicControlNotification$NotificationService.forceForeground(MusicControlNotification.java:215)
    at com.tanguyantoine.react.MusicControlModule$1.onServiceConnected(MusicControlModule.java:243)
    at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:2235)
    at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:2268)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8641)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1133)
  1. Platform ?

    • [ ] iOS
    • [x] Android
3. Device - [ ] Simulator - [x] Real device
bradfloodx commented 2 years ago

Should be fixed in 4.1.1

elliotdickison commented 2 years ago

This is still occurring. Just launched with 1.4.1 and I'm getting these errors on Android 12. I think it's relevant that I recently upgraded my compile target to SDK 31.

android.app.ForegroundServiceStartNotAllowedException: 
  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:3345)
  at android.os.Parcel.createExceptionOrNull (Parcel.java:2432)
  at android.os.Parcel.createException (Parcel.java:2421)
  at android.os.Parcel.readException (Parcel.java:2404)
  at android.os.Parcel.readException (Parcel.java:2346)
  at android.app.IActivityManager$Stub$Proxy.startService (IActivityManager.java:6965)
  at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1926)
  at android.app.ContextImpl.startForegroundService (ContextImpl.java:1892)
  at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:796)
  at androidx.core.content.ContextCompat$Api26Impl.startForegroundService (ContextCompat.java:933)
  at androidx.core.content.ContextCompat.startForegroundService (ContextCompat.java:701)
  at com.tanguyantoine.react.MusicControlNotification$NotificationService.forceForeground (MusicControlNotification.java:215)
  at com.tanguyantoine.react.MusicControlModule$1.onServiceConnected (MusicControlModule.java:243)
  at android.app.LoadedApk$ServiceDispatcher.doConnected (LoadedApk.java:2235)
  at android.app.LoadedApk$ServiceDispatcher$RunConnection.run (LoadedApk.java:2268)
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8663)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:567)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)

I'm doing some research, in the meanwhile @bradleyflood would you mind reopening this?

elliotdickison commented 2 years ago

One suggestion I'm seeing is to pass ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK as a third parameter to startForeground as documented here.

bradfloodx commented 2 years ago

Sure @elliotdickison thanks. Can you test that idea and if it works create a PR? Cheers

elliotdickison commented 2 years ago

Unfortunately I think it's going to be more complicated than that. Here are the results of my research so far:

bradfloodx commented 2 years ago

@elliotdickison You might be better off using https://github.com/doublesymmetry/react-native-track-player

rafaelmaeuer commented 2 years ago

I did some further investigation, updated the project and added some of @elliotdickison suggestions in https://github.com/tanguyantoine/react-native-music-control/pull/407 Please test if it really fixes the problem, I cannot reproduce the error by myself, so its a guess-fix.

I am also not sure, if about the following two:

Leaving some links here that might be related and could help:

marf commented 2 years ago

We have the same issues but unfortunately adding the flag to the manifest does not help. Even adding ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK in startForeground does not seem to fix unfortunately. :(

rafaelmaeuer commented 2 years ago

By wrapping the whole problematic code-block into try-catch (instead of just single parts, excluding the crashing line) seem to fix the crashes (not the issue itself) see commit https://github.com/tanguyantoine/react-native-music-control/commit/bb1b1e951182369d564118b11d5be460efbfd915.

I have updated a Prod-App with this version swrlab/react-native-music-control#v1.5.1 and no more ForegroundServiceStartNotAllowedException so far...

If anyone could verify this, we could try to get the PR merged and switch back to the original source.

marf commented 2 years ago

Yes, in this why crashes can be fixed, the problem is that music cannot be listened in background when this issue happens. The app will not crash anymore but music cannot be played while the app is in background, the definitive fix would be a workaround to avoid the exception at all.

There is a new version of https://github.com/doublesymmetry/react-native-track-player that they said should have fixed the issue, it is in kotlin though and it seems to use a slightly different API for the MusicService, don't know if we can take inspiration from it for the definitive fix in some way.