Lisa Wray
Lisa Wray

Reputation: 2272

AbstractMethodError: abstract method "void android.media.RemoteController$OnClientUpdateListener.onClientSessionEvent

I'm getting a bizarre crash in production on my Android app on three specific Samsung models. It's complaining that I don't override an abstract method onNewSessionEvent, which does not exist in the standard Android platform: http://developer.android.com/reference/android/media/RemoteController.OnClientUpdateListener.html

Fatal Exception: java.lang.AbstractMethodError: abstract method "void android.media.RemoteController$OnClientUpdateListener.onClientSessionEvent(java.lang.String, android.os.Bundle)"
   at android.media.RemoteController.onNewSessionEvent(RemoteController.java:1208)
   at android.media.RemoteController.access$1000(RemoteController.java:61)
   at android.media.RemoteController$MediaControllerCallback.onSessionEvent(RemoteController.java:851)
   at android.media.session.MediaController$MessageHandler.handleMessage(MediaController.java:1073)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:6117)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

The three models are the Galaxy S5 (AT&T and Sprint) and S6 Edge (T-mobile), all on 5.x. I don't have these devices so of course I can't reproduce and troubleshoot locally.

My code does use an OnClientUpdateListener registered on a RemoteController, but that's as far as this makes sense.

Any ideas?

Upvotes: 3

Views: 2545

Answers (1)

ianhanniballake
ianhanniballake

Reputation: 200130

As seen in the RemoteController source code, AOSP's MediaControllerCallback (used to provide backward compatibility between the new media session APIs added in Lollipop with the deprecated RemoteController) only implements onPlaybackStateChanged() and onMetadataChanged().

It seems that on those devices, the API has been silently 'augmented' with attempting to handle onSessionEvent() as well. Unfortunately, one downside of interfaces is that all methods must be implemented so adding new APIs often breaks existing implementations (see ComponentCallbacks2 for an example).

If you want to continue to use RemoteController. OnClientUpdateListener on these Lollipop devices the solution is obvious: implement the method. You now know what the method signature is, so implementing the method (with an empty body) would remove this error message. You may certainly run into additional errors if there are additional methods they expect your OnClientUpdateListener to have (there are quite a few additional ones in MediaController.Callback that are not reflected in the public APIs in OnClientUpdateListener). I'd strongly recommend finding a real device to test your updated OnClientUpdateListener before publishing the app again.

An alternate solution is to use two separate NotificationListenerServices - one for KitKat alone (and would implement OnClientUpdateListener) and a separate one for Lollipop and above that would not. This would allow you to use the Lollipop media playback control APIs and MediaController APIs on Lollipop and above (by reading the Token from EXTRA_MEDIA_SESSION) while maintaining KitKat compatibility.

Upvotes: 2

Related Questions