Bei einer Statusänderung verwendet mein ViewModel derzeit MediaController.setMediaItem, um festzulegen, was gerade abgespielt werden soll.
Ich habe dem Mediencontroller einen Listener hinzugefügt, sodass das ViewModel ein neues Medienelement auswählt und abspielt, wenn sich der Wiedergabestatus in STATE_ENDED ändert. Dies kann auch mit einer „Skip“-Methode meines ViewModel erzwungen werden, die von der Benutzeroberfläche ausgelöst werden kann.
Was ich jetzt tun möchte, ist, dass der Befehl „seek_to_next_media_item“ aus der MediaSessionNotification dasselbe Verhalten auslöst.
Und ich kann anscheinend nicht finden, wie das geht.
Ich habe herausgefunden, wie ich die Schaltfläche in der Benachrichtigung anzeigen kann, indem ich einen Weiterleitungs-Player verwende und Überschreiben von getAvailableCommands().
Aber der weiterleitende Player weiß nichts über mein ViewModel und meines Wissens nach sollte er es auch nicht wissen, da es sich im Dienst befindet und ein Dienst nichts über das ViewModel wissen sollte. Und Player.Listener, der über mein ViewModel Bescheid weiß, hört nicht aufseek_to_next_media_item.
Ich habe diese Anleitung https://github.com/androidx/media/issues/1708 befolgt, durch die Definition meines eigenen Listeners schien es nahe an das zu kommen, was ich wollte.
Ich wollte das tun:
Code: Select all
//In MediaSessionService
override fun onCreate() {
//Creating player as ExoPlayer
val forwardingPlayer = object : ForwardingPlayer(player) {
var myCustomListener: MyCustomListener? = null
override fun getAvailableCommands(): Player.Commands {
val commands = super.getAvailableCommands()
return commands.buildUpon().add(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM).build()
}
override fun addListener(listener: Player.Listener) {
if(listener is MyCustomListener) myCustomListener = listener
super.addListener(listener)
}
override fun removeListener(listener: Player.Listener) {
myCustomListener = null
super.removeListener(listener)
}
override fun seekToNextMediaItem() {
myCustomListener?.onSeekNextMediaItem()
super.seekToNextMediaItem()
}
}
// Creating MediaSession with forwardingPlayer
}
Code: Select all
class MyCustomListener(
val viewModel: MyViewModel
) : Player.Listener {
fun onSeekNextMediaItem() {
Log.d("Listener", "Music listener received on seek next")
viewModel.skipMusic()
}
}
Code: Select all
//In the UI Layer
mediaController.addListener(MyCustomListener(myViewModel))
Ich habe versucht, ihn umzuwandeln, nur für den Fall, dass mein benutzerdefinierter Listener als Unterklasse vorhanden war, aber es ist fehlgeschlagen.
Meine letzte Idee ist, eine Reihe benutzerdefinierter Befehle gemäß dieser Dokumentation zu erstellen: https://developer.android.com/media/med ... e-commands. Lassen Sie den Mediencontroller diese Befehle an den Dienst senden, damit dieser eine Kopie des Status enthält. Auf diese Weise kann es selbst entscheiden, was als nächstes abgespielt wird, aber das scheint kompliziert und fehleranfällig hinsichtlich der Synchronisierung zwischen dem ViewModel-Status und dem Service-Status zu sein.
Wie überschreibe ich das Funktionsverhalten eines Players mit der Logik, die sich in meinem ViewModel befindet? Vielleicht fehlt mir etwas Großes, das es meinem MediaSessionService ermöglicht, mit dem ViewModel zu kommunizieren, aber während meiner langen Recherche konnte ich keines finden. Es kommt mir so vor, als ob mir das richtige Schlüsselwort fehlt.
Vielen Dank für Ihre Hilfe.
Mobile version