1

I'm creating a video App for the Amazon platform. I'm trying to enable the "rewind and fast forward" controls on the remote. But it seems like the app doesn't see this action.

    class VideoActivity : FragmentActivity() {

    private var mediaSession: MediaSessionCompat? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_video)
        initMediaSession()
        supportFragmentManager.beginTransaction()
            .replace(R.id.container, VideoFragment().apply { arguments = intent.extras })
            .commit()
    }

    override fun onDestroy() {
        super.onDestroy()
        mediaSession?.isActive = false
        mediaSession?.release()
    }

    private fun initMediaSession() {
        mediaSession = MediaSessionCompat(applicationContext, "VideoTag")
        mediaSession?.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS)
        val state = PlaybackStateCompat.Builder()
            .setActions(
                PlaybackStateCompat.ACTION_PLAY or PlaybackStateCompat.ACTION_PAUSE or PlaybackStateCompat.ACTION_PLAY_PAUSE or PlaybackStateCompat.ACTION_REWIND
                or PlaybackStateCompat.ACTION_SKIP_TO_NEXT or PlaybackStateCompat.ACTION_SEEK_TO
//                PlaybackStateCompat.ACTION_PLAY_PAUSE or
//                        PlaybackStateCompat.ACTION_FAST_FORWARD
//                        or PlaybackStateCompat.ACTION_REWIND or
//                        PlaybackStateCompat.ACTION_PLAY or
//                        PlaybackStateCompat.ACTION_PAUSE
            )
            .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
            .build()
        mediaSession?.setPlaybackState(state)
        mediaSession?.setCallback(object : MediaSessionCompat.Callback() {
            override fun onCustomAction(action: String?, extras: Bundle?) {
                super.onCustomAction(action, extras)
            }

            override fun onSeekTo(pos: Long) {
                super.onSeekTo(pos)
            }

            override fun onSkipToNext() {
                super.onSkipToNext()
            }

            override fun onFastForward() {
                super.onFastForward()
            }

            override fun onPlay() {
                super.onPlay()
            }

            override fun onPause() {
                super.onPause()
            }

        })
        mediaSession?.isActive = true
        val controll = MediaControllerCompat(this, mediaSession!!)
        MediaControllerCompat.setMediaController(this, controll)
    }

Play/pause works, it switches the player's state, but I cannot intercept this event by media session callback. What did I do wrong?

DanMan
  • 692
  • 9
  • 22
  • An user reported the same problem. Do skip to previous/next work for you? I suspect it sends unusual KeyEvents (e.g. https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_MEDIA_STEP_BACKWARD) which aren't handled by default – user16885569 Oct 23 '22 at 17:07
  • No, any media buttons don't work at all, but the navigation Dpad (up, left, down, right) works perfectly. Even "onKeyDown or onKeyUp" of activity is being triggered for these buttons without any media session. – DanMan Oct 24 '22 at 09:55

1 Answers1

0

I found a solution. Actually solutions. The problem with the media session was a playback state.

mediaSession.setPlaybackState(stateBuilder.setState(PlaybackStateCompat.STATE_PLAYING, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, 1).build());

It requires updating its state every time

But also I figured out I don't need any media sessions because PlaybackTransportControlGlue handles it but does not dispatch it as an action. So I overrode the onKey callback of the PlaybackTransportControlGlue and handle it by myself

override fun onKey(v: View?, keyCode: Int, event: KeyEvent?): Boolean {
    return when {
        event?.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD -> {
            fastForward()
            true
        }
        event?.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MEDIA_REWIND -> {
            rewind()
            true
        }
        else -> super.onKey(v, keyCode, event)
    }
}
DanMan
  • 692
  • 9
  • 22