Open saravr opened 6 months ago
Thanks for reporting!
Is the foreground service really running? not sure why I get inconsistent observation
The service is running but not in the foreground. The session housed by the service is alive as long as the service isn't terminated. To verify, you can do a adb shell dumpsys media_session
to see that the session is there but in state 7 which is the error state.
If it is kept in this state, then the platform will terminate it after a short period of time. To get the service into the foreground again a user interaction from the foreground is required.
how do I make retry work in this case? are there any best practices document that explains how this can be achieved while using Media3?
In this state, it is sufficient to call player.prepare()/play()
again in your restartService
method because the service is still running. However, once the service is off the foreground, resuming is only allowed from the foreground which is normally a user interaction on an app UI that is in the foreground (for instance an activity), or from a notification.
My understanding is that from the service itself that is in the background, the only option would be to post a notification when you detect the error. The user can then use the notification to initiate resuming playback which puts the service into the foreground again.
One way to do such a notification is implementing playback resumption with a MediaLibraryService
. In this case a user can retry by using the playback resumption notification posted by System UI (or pressing play on the BT headset). It has the advantage that it knows about the last playing item and will look identically to the notification/UMO the user is used to. The disadvantage is that it isn't very prominently placed.
I tried this out by adding playback resumption to the session demo app. With this in place the workflow is as follows. I changed the URI of "Intro - The Way Of Waking Up" of the Kyoto Connection in catalogue.json
so that the URI is producing an error because the file does not exist:
playbackStateCompat.getState() == 7
; verify with adb shell dumpsys media_session
)I think this is how you can solve this. If you don't want to use playback resumption, you can instead post your own notification that the user can see. This has the advantage that it is more prominent and it's more likely the user sees it. The playback resumption notification is a bit hidden. The disadvantage of doing your own notification is that you need to do it on your own which may be difficult or a bit of effort if it should look the same as the UMO.
@marcbaechinger thank you so much for the detailed response. I will evaluate and try this approach out. I am noticing that some of the popular media playback apps maintain the notification even when the network is turned off in the middle. Explicit notification to restart playback is ok but ideally, I would like to have this behavior where notification is "maintained" throughout. Anyways, I will try this approach and will let know how this helps.
I want to retry playback when a player error is detected (SourceException indicating timeout). However, while attempting to retry, I get this exception. UI (MediaController) is intact (player in idle state). My retry code in the service determines that foreground service is not running (as determined by
isServiceRunningInForeground()
) in the following code. However, I see it is still running when I use the adb shell command.I also see
allowStartForeground=PROC_STATE_TOP
in the above command output (while playback is going on). And then it changes to DENIED which indicatesHere is my code: