androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.73k stars 416 forks source link

Missing Notifications when following exoplayer migration guide. #197

Open fourofspades opened 2 years ago

fourofspades commented 2 years ago

I have been attempting to convert my app from exoplayer to media3, and using the migration guide here:

https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide

It's been going reasonably well (despite all the examples and documentation being in Kotlin, and my app and knowledge soundly in Java). I have my streaming radio player app compiling and working. It's really only the notifications I need to get working. Currently my app doesn't show show media notification,

The migration guide states:

The MediaLibraryService supports media notifications automatically and the PlayerNotificationManager can be removed when using a MediaLibraryService or MediaSessionService.

This is not the case for me, and I'm not entirely sure what's going on. As with Exoplayer, the service/notification/session interactions are all very confusing and constantly changing.

Here is my service.

https://pastebin.com/MiK9Misj

Any pointers or clarifications on the migration guide would be appreciated.

marcbaechinger commented 2 years ago

Your service looks like your app is not using a MediaController for sending playback commands. The code sample you sent is for instance overriding onBind() in a way that I think it doesn't work. I think for the service to properly work a controller/browser needs to be built that then binds to the service with an actions that determines which service interface to use.

When looking at your service I think you are requesting another interface that you return in onBind that you have overridden. If you do this without building a MediaController, then MediaSessionService.connect() is never called. I don't think this is the intended way of using the service that we provide support for. Honestly, I actually think MediaSession.onBind() should be final, but I think it isn't because MediaLibraryService is extending from it and needs to override onBind. We should probably look into this and at least document this properly. Apologies that this isn't the case already. Apps are not supposed to do that.

I would recommend to remove your override of onBind/onUnbind and instead use a MediaController:

val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java))
val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
var controller: MediaController
controllerFuture.addListener(
    {
        controller = controllerFuture.get()
        // call playback command methods on the controller like `controller.play()`
    },
    MoreExecutors.directExecutor()
)
PaulWoitaschek commented 2 years ago

should be final, but I think it isn't because MediaLibraryService is extending from it and needs to override onBind

@marcbaechinger You could implemenet that using package private visibility to prevent such missusage.

public class MediaSessionService extends Service {
  @Override
  public final IBinder onBind(Intent intent) {
    return onBindHidden(intent);
  }

  IBinder onBindHidden(Intent intent) {
    ...
  }
}
public class MediaLibraryService extends MediaSessionService {

  @Override
  IBinder onBindHidden(Intent intent) {
    // ...
  }
}
marcbaechinger commented 1 year ago

(@PaulWoitaschek Just as an aside: Yeah, what I meant is that this was probably the reason someone did it like that. The thing is that now as per AndroidX process we are not allowed to change the public API once we are in Beta. Making onBind final would change the public API pf the MediaSession though.)

XilinJia commented 3 months ago

Hum, overriding onBind is not intended while it's allowed is a bummer. I spent a day trying to figure out why notification doesn't show up when I transitioned the service from MediaSessionService to MediaLibraryService. With the former, notification is working when onBind was overridden.