doublesymmetry / react-native-track-player

A fully fledged audio module created for music apps. Provides audio playback, external media controls, background mode and more!
https://rntp.dev/
Apache License 2.0
3.18k stars 981 forks source link

Unable to start service MusicService with null: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false #2244

Open brad-sf opened 5 months ago

brad-sf commented 5 months ago

Describe the Bug Daily crash reports of Unable to start service com.doublesymmetry.trackplayer.service.MusicService with null: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false

Steps To Reproduce Unknown. Will update if I can replicate consistently.

Code To Reproduce NA

Replicable on Example App? Not yet.

Environment Info:

How I can Help Looking into it.

brad-sf commented 5 months ago

Looking at all the older issues related to this, it appears this issue should be fixed in 4.0.1, but it's not for me. Still getting this crash report several times a day :(

brad-sf commented 5 months ago

Stack trace from BugSnag:

ActivityThread.java:4880 android.app.ActivityThread.handleServiceArgs
Unknown android.app.ActivityThread.-$$Nest$mhandleServiceArgs
ActivityThread.java:2314 android.app.ActivityThread$H.handleMessage
Handler.java:106 android.os.Handler.dispatchMessage
Looper.java:205 android.os.Looper.loopOnce
Looper.java:294 android.os.Looper.loop
ActivityThread.java:8248 android.app.ActivityThread.main
Method.java:-2 java.lang.reflect.Method.invoke
RuntimeInit.java:552 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run
ZygoteInit.java:971 com.android.internal.os.ZygoteInit.main
Caused By: android.app.ForegroundServiceStartNotAllowedException · Service.startForeground() not allowed due to mAllowStartForeground false: service com.tutusgumboots.evergrace/com.doublesymmetry.trackplayer.service.MusicService
ForegroundServiceStartNotAllowedException.java:54 android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel
lovegaoshi commented 5 months ago

after some research I dont think this is supposed to be fixed in recent versions, really.

The root cause is android disabled starting a foreground service from a background activity since 8 or 12. Because RNTP does kill the foreground service quite liberally, this quickly becomes a problem once the activity is sent to background/cached process. There are ways around it, like disabling battery optimization; but the fact the foreground service is killed and restarted is a problem itself; unlike the flutter alternative (audio_service) RNTP actually does NOT correctly link service back to activity, so it introduces another problem where closing activity may not kill service. So the options are:

  1. do NOT kill foreground service like https://github.com/lovegaoshi/react-native-track-player/commit/9afe35b163c84bf69ba484699dc8aac94dfc00cb this will keep the process to be always running, never backgrounded/cached; this will obviously introduce more battery use; I observed ~0.5-1% battery use over 5 hours or so on Samsung S21. do note Youtube (revanced) and AIMP also do this and this is how I intend to go with. flutter's audio_service basically also have this as an option: https://github.com/ryanheise/audio_service/issues/994#issuecomment-1423601924

  2. turn off battery optimization, which effectively does 1.

  3. turn on ways to enable starting a foreground service from a background activity like SYSTEM_ALERT_WINDOW

  4. target android 7?

I seriously doubt a real solution exists (some if logic to MS.kt L123) otherwise the flutter folks would have found it already. But no one reported a reliable way to reproduce this bug either. For example, I can force terminate the service, app goes to background, though the notification lingers; if I interact with the notification then this is an exception allowed to start foreground service, I dont really understand how this bug happens

brad-sf commented 5 months ago

Great info thanks @lovegaoshi I'm going to go with your 1. commit for now and see if it helps my crashes :)

brad-sf commented 5 months ago

patch-package patch here if anyone else wants to try it

diff --git a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
index 9d6d869..a0a150e 100644
--- a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
+++ b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
@@ -587,9 +587,10 @@ class MusicService : HeadlessJsTaskService() {
                             scope.launch {
                                 delay(stopForegroundGracePeriod.toLong() * 1000)
                                 if (shouldStopForeground()) {
-                                    @Suppress("DEPRECATION")
-                                    stopForeground(removeNotificationWhenNotOngoing)
-                                    Timber.d("Notification has been stopped")
+                                   Timber.d("Notification should have been stopped - quick fix hack")
+                                    //@Suppress("DEPRECATION")
+                                    //stopForeground(removeNotificationWhenNotOngoing)
+                                    //Timber.d("Notification has been stopped")
                                 }
                             }
                         }
lovegaoshi commented 5 months ago

I'm seeing some absurd wakelock and cpu use duration that could be RN apps specific, as MusicService doesnt release wakelocks (headlessJsTaskService). One possible solution could be to move wakelock within: see https://github.com/lovegaoshi/react-native-track-player/commit/2daba94fb05d0bedef6e4e168c9b0f8e32f531a8 and https://github.com/lyswhut/react-native-track-player/commit/bb80e13aa8ed97224ebd3a9cce39e629d0043999

though since AS moved their energy profiler to system trace, I dont know where to find wakelock profiling information anymore, if this my suspicion on the wakelock is even correct

lovegaoshi commented 4 months ago

ive been pretty satisfied with my wakelock patch above and the barrey use, and keeping foregrounf service is veru nice.

the wakelock patch needs to expose wakelock as public and makes more sense to patch after the Aa work.

brad-sf commented 4 months ago

IMG_6948

do NOT kill foreground service like https://github.com/lovegaoshi/react-native-track-player/commit/9afe35b163c84bf69ba484699dc8aac94dfc00cb

Unfortunately this did not change things for me in prod :(

I'll try your wake lock fix and let you know how that goes :)

lovegaoshi commented 4 months ago

im out of wits :/ so it has to be where it's listing foreground tasks and its returning null..? i cant reproduce so cant help

On Tue, Feb 6, 2024, 8:28 PM Brad SF @.***> wrote:

IMG_6948.jpeg (view on web) https://github.com/doublesymmetry/react-native-track-player/assets/1085976/1972cb0e-2673-40ae-9f23-c1bd537369ff

do NOT kill foreground service like @.*** https://github.com/lovegaoshi/react-native-track-player/commit/9afe35b163c84bf69ba484699dc8aac94dfc00cb

Unfortunately this did not change things for me in prod :(

I'll try your wake lock fix and let you know how that goes :)

— Reply to this email directly, view it on GitHub https://github.com/doublesymmetry/react-native-track-player/issues/2244#issuecomment-1931260986, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVUM3PZYUUZ2FMRT2ALYSL7IBAVCNFSM6AAAAABCSFD5U2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZRGI3DAOJYGY . You are receiving this because you were mentioned.Message ID: @.*** com>

TobiDevloft commented 4 months ago

We are seeing a lot of these errors as well, resulting quite a few crashes for the user. The error does seem to only occur on devices running Android 14.

image
TobiDevloft commented 4 months ago

Seems to be a duplicate of:

https://github.com/doublesymmetry/react-native-track-player/issues/2231 https://github.com/doublesymmetry/react-native-track-player/issues/2198

and several closed issues.

Is that something you guys have on your radar? @dcvz

mmmoussa commented 4 months ago

We have shipped the workaround of not killing the foreground service and found it to be effective so far. @brad-sf it is likely that you either did not apply the patch correctly or the continued issue you're seeing is from old versions that are still being used by your users.

StriderHND commented 4 months ago

We have shipped the workaround of not killing the foreground service and found it to be effective so far. @brad-sf it is likely that you either did not apply the patch correctly or the continued issue you're seeing is from old versions that are stibeing used by your user

@mmmoussa this workaround that you mention is avaialble in the current version of the framework? or is located somewhere else?

I just started to investigate this issue and I see a lot of users experiencing this behaviour.

kyo-torstar commented 4 months ago

It's getting on my nerves that there are hundreds of reported crashes related to this issue everyday. The app was just deployed with latest version 4.0.1 few days ago and Its downgrading the UX. Is there a workaround for this? @brad-sf how is the result for the wake lock fix?

Screenshot 2024-02-14 at 12 43 09 PM
NadeemKhanFh commented 4 months ago

@mmmoussa whats this workaround? how can we fix that?

kyo-torstar commented 4 months ago

this is the crashlytics log I have, and the function caused the crash has a remark related to https://github.com/doublesymmetry/react-native-track-player/issues/1666 Screenshot 2024-02-15 at 9 27 55 AM

kyo-torstar commented 4 months ago

According to the crash logs, they all happened within the 1st second. I wonder if it is related to the TrackPlayer.setupPlayer() function call while the app is bootstrapping in the background. Screenshot 2024-02-15 at 9 57 40 AM

lovegaoshi commented 4 months ago

whats ur MS.kt L125? nightly is stopForeground i doubt that is the one; if it's startForeground(EMPTY_NOTIFICATION_ID, notification) and android 14 u can try https://github.com/lovegaoshi/react-native-track-player/commit/1145e2da93647cab93bf118cbf22177433fbe642 (add foreground service type to startForeground) but i doubt it helps

kyo-torstar commented 4 months ago

Th

whats ur MS.kt L125? nightly is stopForeground i doubt that is the one; if it's startForeground(EMPTY_NOTIFICATION_ID, notification) and android 14 u can try lovegaoshi@1145e2d (add foreground service type to startForeground) but i doubt it helps

its caused by stopForeground(true) on L125 MusicService.kt. But tracing backward, I find the initial call should be onStartCommand, a function triggered by HeadlessJsTaskService. Therefore, on the frontend react native, TrackPlayer.registerPlaybackService function call may cause the crash.

Screenshot 2024-02-15 at 10 21 05 AM
lovegaoshi commented 4 months ago

and can you reliably reproduce instead from crash logs?

On Thu, Feb 15, 2024, 7:27 AM kyo-torstar @.***> wrote:

Th

whats ur MS.kt L125? nightly is stopForeground i doubt that is the one; if it's startForeground(EMPTY_NOTIFICATION_ID, notification) and android 14 u can try @.*** https://github.com/lovegaoshi/react-native-track-player/commit/1145e2da93647cab93bf118cbf22177433fbe642 (add foreground service type to startForeground) but i doubt it helps

its caused by stopForeground(true) on L125 MusicService.kt. But tracing backward, I find the initial call should be onStartCommand, a function triggered by HeadlessJsTaskService. Therefore, on the frontend react native, TrackPlayer.registerPlaybackService function call may cause the crash. Screenshot.2024-02-15.at.10.21.05.AM.png (view on web) https://github.com/doublesymmetry/react-native-track-player/assets/120053121/50930d7f-c80f-442d-b249-329617e322ee

— Reply to this email directly, view it on GitHub https://github.com/doublesymmetry/react-native-track-player/issues/2244#issuecomment-1946322517, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVX4KYXZDYJOZMG6ZB3YTYSMJAVCNFSM6AAAAABCSFD5U2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBWGMZDENJRG4 . You are receiving this because you were mentioned.Message ID: @.*** com>

kyo-torstar commented 4 months ago

and can you reliably reproduce instead from crash logs? On Thu, Feb 15, 2024, 7:27 AM kyo-torstar @.> wrote: Th whats ur MS.kt L125? nightly is stopForeground i doubt that is the one; if it's startForeground(EMPTY_NOTIFICATION_ID, notification) and android 14 u can try @. [lovegaoshi@1145e2d](https://github.com/lovegaoshi/react-native-track-player/commit/1145e2da93647cab93bf118cbf22177433fbe642) (add foreground service type to startForeground) but i doubt it helps its caused by stopForeground(true) on L125 MusicService.kt. But tracing backward, I find the initial call should be onStartCommand, a function triggered by HeadlessJsTaskService. Therefore, on the frontend react native, TrackPlayer.registerPlaybackService function call may cause the crash. Screenshot.2024-02-15.at.10.21.05.AM.png (view on web) https://github.com/doublesymmetry/react-native-track-player/assets/120053121/50930d7f-c80f-442d-b249-329617e322ee — Reply to this email directly, view it on GitHub <#2244 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVX4KYXZDYJOZMG6ZB3YTYSMJAVCNFSM6AAAAABCSFD5U2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBWGMZDENJRG4 . You are receiving this because you were mentioned.Message ID: @.*** com>

we reproduced it few times only but we could not conclude the reliable step to replicate it. It looks random that it may relate to racing conditions upon bootstrap. I modified the startup function as following:

setTimeout(() => {
  TrackPlayer.registerPlaybackService(() =>
    require('@services/TrackPlayerService'),
  );

  setTimeout(async () => {
    await TrackPlayer.setupPlayer();
    await TrackPlayer.updateOptions(options); 
  }, 3000);
}, 3000);
brad-sf commented 4 months ago

I'm definitely getting LESS of this crash report since trialing the patch fix above.

But yes I agree there also appears to be some remaining crashes related to a race condition because they fire immediately on app launch (according to crash logs).

I'll try the above setTimeout and see if that clears all the errors.

If that's the case I guess we have two issues.. one on launch and one in general usage.

kyo-torstar commented 4 months ago

@brad-sf @lovegaoshi I look deeper, It should be related to the setupPlayer function being called when the app is in the background state. There should be a glimpse of moment the app is in background state when setupPlayer is called. It should be triggered by this

        Intent(context, MusicService::class.java).also { intent ->
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
            context.bindService(intent, this, Context.BIND_AUTO_CREATE)
        }

To minimize the possibility of this from happening, we can do something like

TrackPlayer.registerPlaybackService(() =>
  require('@services/TrackPlayerService'),
);
const setupDelay = 1000;

const useTrackPlayer = () => {
  const [isServiceRegistered, setIsServiceRegistered] = useState(false);
  useEffect(() => {
      let initTimer = setTimeout(() => {
        if (state.appState === 'active' && !isServiceRegistered) {
          // inside this function calls:
          // await TrackPlayer.setupPlayer();
          // await TrackPlayer.updateOptions(options);
          // setIsServiceRegistered(true);
          initAudioPlayer(playerStatus); 
        }
      }, setupDelay);

      return () => {
        clearTimeout(initTimer);
      };
    }, [state, isServiceRegistered]);
}

This is a temp workaround, the solution should be applied at the setupPlayer function in MusicService.kt, a foreground has to be done

if (isAppOnForeground((context))) {
  // promise.reject here
}
...
Intent(context, MusicService::class.java).also { intent ->
...

The Java implementation from https://reactnative.dev/docs/headless-js-android

    private boolean isAppOnForeground(Context context) {
        /**
         We need to check if app is in foreground otherwise the app will crash.
         https://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
         **/
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses =
                activityManager.getRunningAppProcesses();
        if (appProcesses == null) {
            return false;
        }
        final String packageName = context.getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance ==
                    ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
                    appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }
lovegaoshi commented 4 months ago

But why is your app in the background state when it's starting up? unless I immediately press back when opening the app, and startService is caught in that way? it would really help if there's a reproducible repo; I've never seen the example app or my app going ANR when starting up.

kyo-torstar commented 4 months ago
Screenshot 2024-02-20 at 1 23 54 PM

the crash logs all show that they happen less than a second. It could be the reason the setupPlayer function is called during app start. e.g. I put setupPlayer in the App.tsx function body, for example

useEffect(() => {
  setupPlayer()
}, []) 
trix0 commented 4 months ago

Related to https://issuetracker.google.com/issues/307329994 ?

kyo-torstar commented 4 months ago

Related to https://issuetracker.google.com/issues/307329994 ?

possibly, but it looks like no one can reproduce it locally. This was what I thought when I was trying to reproduce the crash as I experience no crash. However, I found several crash logs related to my tests later. I think the app was crashed and was restarted when It was brought back from background / during bootstrap.

kyo-torstar commented 3 months ago

update to potential fix: https://issuetracker.google.com/issues/307329994#comment56 further reference: https://stackoverflow.com/questions/77680265/service-startforeground-not-allowed-due-to-mallowstartforeground-false-androi

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null) {
        startForeground();    //or wherever you call it: check the Intent before!
    }
}
Nadimkhan120 commented 3 months ago

@kyo-torstar where we will write this code?

lovegaoshi commented 3 months ago

youd wrap startAndStopEmptyNotificationToAvoidANR() https://github.com/lovegaoshi/react-native-track-player/commit/95c26d92815c1f9d55b0c401e1fd4244e2f98c77 but why is this (service killed n restarted due to oom) related to crush on app start? has anyone done log intent before app crash?

Nadimkhan120 commented 3 months ago

@lovegaoshi i tried your solution its not working, on android 14, its not working in app killed state, otherwise working finr

lovegaoshi commented 3 months ago

buddy if theres no error trace how am i supposed to help in any way

and like i said i cant reliably reproduce it

On Thu, Mar 7, 2024, 1:56 PM Nadimkhan120 @.***> wrote:

@lovegaoshi https://github.com/lovegaoshi i tried your solution its not working, on android 14, its not working in app killed state, otherwise working finr

— Reply to this email directly, view it on GitHub https://github.com/doublesymmetry/react-native-track-player/issues/2244#issuecomment-1984569665, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVRE43CWL3TY7Y5NUW3YXDPBDAVCNFSM6AAAAABCSFD5U2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBUGU3DSNRWGU . You are receiving this because you were mentioned.Message ID: @.*** com>

sampie777 commented 3 months ago

Indeed duplicate of #2184 and #2231. But I'll be posting my 2 cents here, as this discussion seems to be the most promising.

Using react-native-track-player 4.0.1 and react-native 0.72.10, I see this error on Android 14 devices, Samsung Galaxy A23 (SM-A235F) to be specific. Apparently, Android 14 introduced something new causing this bug and we need a patch for Android 14 (and above, probably). [update 21/03/2024] I see this error mostly on Android 14 but a couple of times on 13. Devices SM-A235F, SM-A245F, SM-A042F, CPH2387, Pixel 6 Pro, and one time on a Pixel 7a during local development.

In the code TrackPlayer.setupPlayer() is only called after the app is loaded. I have no insight in whether the app was in background or foreground at the time of the crash.

Here are two different crash logs:


android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false: service nl.sajansen.hymnbook2/com.doublesymmetry.trackplayer.service.MusicService
  android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
  android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
  android.os.Parcel.readParcelableInternal (Parcel.java:4882)
  android.os.Parcel.readParcelable (Parcel.java:4864)
  android.os.Parcel.createExceptionOrNull (Parcel.java:3064)
  android.os.Parcel.createException (Parcel.java:3053)
  android.os.Parcel.readException (Parcel.java:3036)
  android.os.Parcel.readException (Parcel.java:2978)
  android.app.IActivityManager$Stub$Proxy.setServiceForeground (IActivityManager.java:7214)
  android.app.Service.startForeground (Service.java:775)
  com.doublesymmetry.trackplayer.service.MusicService.startAndStopEmptyNotificationToAvoidANR (MusicService.kt:123)
  com.doublesymmetry.trackplayer.service.MusicService.onStartCommand (MusicService.kt:98)
  android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5268)
  android.app.ActivityThread.-$$Nest$mhandleServiceArgs (Unknown source)
  android.app.ActivityThread$H.handleMessage (ActivityThread.java:2531)
  android.os.Handler.dispatchMessage (Handler.java:106)
  android.os.Looper.loopOnce (Looper.java:230)
  android.os.Looper.loop (Looper.java:319)
  android.app.ActivityThread.main (ActivityThread.java:8893)
  java.lang.reflect.Method.invoke (Method.java:-2)
  com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:608)
  com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1103)
java.lang.RuntimeException: Unable to start service com.doublesymmetry.trackplayer.service.MusicService@7af617a with null: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false: service nl.sajansen.hymnbook2/com.doublesymmetry.trackplayer.service.MusicService
  android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5286)
  android.app.ActivityThread.-$$Nest$mhandleServiceArgs (Unknown source)
  android.app.ActivityThread$H.handleMessage (ActivityThread.java:2531)
  android.os.Handler.dispatchMessage (Handler.java:106)
  android.os.Looper.loopOnce (Looper.java:230)
  android.os.Looper.loop (Looper.java:319)
  android.app.ActivityThread.main (ActivityThread.java:8893)
  java.lang.reflect.Method.invoke (Method.java:-2)
  com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:608)
  com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1103)

And another one of which I don't have the device information anymore:

android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service nl.sajansen.hymnbook2/com.doublesymmetry.trackplayer.service.MusicService
  android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
  android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
  android.os.Parcel.readParcelableInternal (Parcel.java:4787)
  android.os.Parcel.readParcelable (Parcel.java:4755)
  android.os.Parcel.createExceptionOrNull (Parcel.java:3018)
  android.os.Parcel.createException (Parcel.java:3007)
  android.os.Parcel.readException (Parcel.java:2990)
  android.os.Parcel.readException (Parcel.java:2932)
  android.app.IActivityManager$Stub$Proxy.startService (IActivityManager.java:6214)
  android.app.ContextImpl.startServiceCommon (ContextImpl.java:1967)
  android.app.ContextImpl.startForegroundService (ContextImpl.java:1933)
  android.content.ContextWrapper.startForegroundService (ContextWrapper.java:839)
  android.content.ContextWrapper.startForegroundService (ContextWrapper.java:839)
  com.doublesymmetry.trackplayer.module.MusicModule.setupPlayer (MusicModule.kt:239)
  java.lang.reflect.Method.invoke (Method.java:-2)
  com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
  com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:188)
  com.facebook.jni.NativeRunnable.run (NativeRunnable.java:-2)
  android.os.Handler.handleCallback (Handler.java:942)
  android.os.Handler.dispatchMessage (Handler.java:99)
  com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
  android.os.Looper.loopOnce (Looper.java:226)
  android.os.Looper.loop (Looper.java:313)
  com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:228)
  java.lang.Thread.run (Thread.java:1012)
newme616 commented 3 months ago

I have the same issue

khc196 commented 3 months ago

after some research I dont think this is supposed to be fixed in recent versions, really.

The root cause is android disabled starting a foreground service from a background activity since 8 or 12. Because RNTP does kill the foreground service quite liberally, this quickly becomes a problem once the activity is sent to background/cached process. There are ways around it, like disabling battery optimization; but the fact the foreground service is killed and restarted is a problem itself; unlike the flutter alternative (audio_service) RNTP actually does NOT correctly link service back to activity, so it introduces another problem where closing activity may not kill service. So the options are:

  1. do NOT kill foreground service like lovegaoshi@9afe35b this will keep the process to be always running, never backgrounded/cached; this will obviously introduce more battery use; I observed ~0.5-1% battery use over 5 hours or so on Samsung S21. do note Youtube (revanced) and AIMP also do this and this is how I intend to go with. flutter's audio_service basically also have this as an option: ForegroundServiceStartNotAllowedException ryanheise/audio_service#994 (comment)
  2. turn off battery optimization, which effectively does 1.
  3. turn on ways to enable starting a foreground service from a background activity like SYSTEM_ALERT_WINDOW
  4. target android 7?

I seriously doubt a real solution exists (some if logic to MS.kt L123) otherwise the flutter folks would have found it already. But no one reported a reliable way to reproduce this bug either. For example, I can force terminate the service, app goes to background, though the notification lingers; if I interact with the notification then this is an exception allowed to start foreground service, I dont really understand how this bug happens

  1. works for me. Thanks.
Nadimkhan120 commented 3 months ago

@khc196 how did you manage to get it work?

kyo-torstar commented 3 months ago

We need to find a way to reproduce the crash. It may not be reliably to reproduce it but it should increase the chance of experiencing it. Does the crash impact the user experience or it only crashes after the app is killed manually.

ymkwon3 commented 3 months ago

I'm not sure if it's true yet, but when I used the device care optimization widget on the home screen, the error occurred with a probability of 100%.

  1. Run the application
  2. Click the home screen button
  3. Click the Optimize widget on the home screen
  4. In that case, when the service scheduling time comes, an intent null value is received and an error occurs.
lovegaoshi commented 3 months ago

@ymkwon3 thanks for the lead!~i still cant reproduce though~

I finally saw this error with the example app, though the way reproduced I saw the error after PROCESS ENDED. so i dont think it affects UX in any way bc app is dead anyways (specifically for RN apps at least, as service cannot linger with activity being shut down. native is another story).

kyo-torstar commented 3 months ago

@lovegaoshi @ymkwon3 I found a reliable way to reproduce it 100% and it is more common in terms of usage. This is related to the notification channel setup by the library. Steps to reproduce:

  1. start the app with the library initialized
  2. put the app to background
  3. go to settings of the app and turn the notification off
  4. wait for 5-20 seconds
  5. the app crashes in the background

i tried to turn off the notification channel and the app can still play music in the background. What is the reason behind for subscribing those notification channels?

Screenshot 2024-04-01 at 2 53 51 PM
lovegaoshi commented 3 months ago

@kyo-torstar thanks for another lead! i think this is an expected OS behavior though that the app is killed/restarted upon removing certain permissions. any music app will close like that the temp channel is from https://github.com/doublesymmetry/react-native-track-player/pull/1974

kyo-torstar commented 3 months ago

@lovegaoshi its interesting to see that, even if i turn off the notification channels, i still can play the music in the background as normal.

Another test that it does not crash is by playing the music in the background before turning the notification off: start the app with the library initialized

  1. play music and put the app to background
  2. go to settings of the app and turn the notification off
  3. no crash but the music stops

PS: I tried Spotify, i turned off the notification and there is no crash when music is on or off Edit: The app does not crash if i turn off the "Now Playing" and "temporary_channel" notification, it only crashes when ALL of the notification of the app is turned off

lovegaoshi commented 3 months ago

I dont think the channels actually do anything, turning them on and off have 0 effects; but turning off the notification permission (or any permission, really) will trigger an app close/restart, and this should be universal.

kyo-torstar commented 2 months ago

@lovegaoshi I did this fix https://github.com/kyo-torstar/react-native-track-player/pull/1/files to avoid foreground notification service from starting when the app is in background. It solves the crash of turning off notification when the app is in background. @ymkwon3 not sure about your case, I could not replicate with your steps. You may try if my solution works on your case.

kyo-torstar commented 2 months ago

update: after applying the fix and deploying to the production, that type of crash is finally gone. The fix references startForegroundIfNecessary function to catch the exception in case the foreground service is executed in background.

erinpeach commented 2 months ago

@kyo-torstar - seconding your success. My team shipped a change based on your fix and haven't see the error re-occur yet in our app. 👏 Awesome job hunting that down and finding a fix.

dcvz commented 2 months ago

@lovegaoshi I did this fix https://github.com/kyo-torstar/react-native-track-player/pull/1/files to avoid foreground notification service from starting when the app is in background. It solves the crash of turning off notification when the app is in background. @ymkwon3 not sure about your case, I could not replicate with your steps. You may try if my solution works on your case.

This doesn’t exactly stop it from performing the action but it does catch the exception so it doesn’t crash the process, which is still good. Will try to read the latest messages here in the next week.

devartwa commented 1 week ago

any update?

Kirillsocivka commented 1 week ago

any update?

+1

lovegaoshi commented 1 week ago

unless anyone can post reproducible steps, ur +1 wont help going anywhere except keeping this thread alive. otherwise read the thread, either keep the service always alive or catch the exception and pretend nothing happened.

On Mon, Jun 24, 2024, 5:00 AM Kirillsocivka @.***> wrote:

any update?

+1

— Reply to this email directly, view it on GitHub https://github.com/doublesymmetry/react-native-track-player/issues/2244#issuecomment-2186409758, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVVYZMLB3ULFWW4EDW3ZJAC65AVCNFSM6AAAAABCSFD5U2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCOBWGQYDSNZVHA . You are receiving this because you were mentioned.Message ID: @.*** com>