Поэтому в настоящее время при изменении состояния моя ViewModel использует MediaController.setMediaItem, чтобы установить, что должно воспроизводиться в данный момент.
Я добавил прослушиватель в медиа-контроллер, чтобы при изменении состояния воспроизведения на STATE_ENDED ViewModel выбирала новый медиа-элемент и воспроизводила его. Это также можно принудительно выполнить с помощью метода «skip» моей модели ViewModel, который может быть запущен пользовательским интерфейсом.
Теперь я хочу, чтобы команда search_to_next_media_item из MediaSessionNotification вызывала такое же поведение.
И я не могу найти, как это сделать.
Я нашел, как сделать так, чтобы кнопка отображалась в уведомлении с помощью пересылки player и переопределение getAvailableCommands().
Но пересылающий проигрыватель не знает о моей ViewModel, и, насколько я понимаю, он не должен этого знать, поскольку он находится в службе, а служба не должна знать о ViewModel. А Player.Listener, который знает о моей ViewModel, не прослушивает search_to_next_media_item.
Я следовал этому руководству https://github.com/androidx/media/issues/1708, определив свой собственный прослушиватель, похоже, он приблизился к тому, что я хотел.
Я хотел сделать это:
Код: Выделить всё
//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
}
Код: Выделить всё
class MyCustomListener(
val viewModel: MyViewModel
) : Player.Listener {
fun onSeekNextMediaItem() {
Log.d("Listener", "Music listener received on seek next")
viewModel.skipMusic()
}
}
Код: Выделить всё
//In the UI Layer
mediaController.addListener(MyCustomListener(myViewModel))
Я пытался его привести, на случай, если мой пользовательский прослушиватель был там как подкласс, но это не удалось.
Моя последняя идея — создать кучу пользовательских команд в соответствии с этой документацией: https://developer.android.com/media/med ... e-commands. И пусть медиа-контроллер отправит эти команды службе, чтобы она хранила копию состояния. Таким образом, он может самостоятельно решить, во что играть дальше, но это кажется запутанным и подверженным ошибкам в отношении синхронизации между состоянием ViewModel и состоянием службы.
Как переопределить поведение функции проигрывателя с помощью логики, которая находится в моей ViewModel? Возможно, мне не хватает чего-то огромного, что позволяет моему MediaSessionService взаимодействовать с ViewModel, но за время моих долгих исследований я не смог его найти. Кажется, я пропустил нужное ключевое слово.
Большое спасибо за помощь.
Подробнее здесь: https://stackoverflow.com/questions/798 ... n-my-viewm
Мобильная версия