Introduction
The android media viewer mediaplayer MediaControllerCompat tutorial series describes how to setup the MediaControllerCompat with the MediaPlayer UI. And its relationship with the MediaSessionCompat.
The role of the MediaController is to directly interface with the application UI and to pass requests down to the MediaSession via the transport controls.
Get Code
The code can be found on github from the following instructions below
https://github.com/mobapptuts/media-thumbnail-viewer.git Tag
media-viewer-mediacontroller
or you can run this command
git clone https://github.com/mobapptuts/media-thumbnail-viewer.git –branch
media-viewer-mediacontroller
This video describes how to import the code from github using android studio and also how to use git tags
Steps
Add the application members
The MediaControllerCompat role is to communicate with the UI, receive notifications from the MediaSessionCompat and to pass requests to the MediaSessionCompat.
The MediaControllerCompat.TransportControls will be used to send media requests to the MediaSession from the UI.
The MediaControllerCompat.Callback will be used to receive state updates from the MediaSession and to update the UI.
private MediaControllerCompat mController; private MediaControllerCompat.TransportControls mControllerTransportControls; private MediaControllerCompat.Callback mControllerCallback = new MediaControllerCompat.Callback() { @Override public void onPlaybackStateChanged(PlaybackStateCompat state) { super.onPlaybackStateChanged(state); switch (state.getState()) { case PlaybackStateCompat.STATE_PLAYING: mPlayPauseButton.setImageResource(R.mipmap.ic_media_pause); break; case PlaybackStateCompat.STATE_PAUSED: mPlayPauseButton.setImageResource(R.mipmap.ic_media_play); break; case PlaybackStateCompat.STATE_STOPPED: mPlayPauseButton.setImageResource(R.mipmap.ic_media_play); break; } } };
Setup the activity members
Note with MediaSessionCompat.setFlags() we are enabling the MediaControllerCompat to receive requests from media buttons and to send media requests to the MediaSessionCompat.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video_play); mPlayPauseButton = (ImageButton) findViewById(R.id.videoPlayPauseButton); mSurfaceView = (SurfaceView) findViewById(R.id.videoSurfaceView); Intent callingIntent = this.getIntent(); if(callingIntent != null) { mVideoUri = callingIntent.getData(); } mSession = new MediaSessionCompat(this, TAG); mSession.setCallback(new MediaSessionCallback(this)); mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mPBuilder = new PlaybackStateCompat.Builder(); mController = new MediaControllerCompat(this, mSession); mControllerTransportControls = mController.getTransportControls(); }
Modify the UI to use the controller transport commands instead of the calling the MediaPlayer directly
Change the play and pause for the onclick button
public void playPauseClick(View view) { if(mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING) { mControllerTransportControls.pause(); } else if (mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_PAUSED || mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_STOPPED || mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_NONE) { mControllerTransportControls.play(); } }
Change the activity onPause to the transport pause
@Override protected void onPause() { if(mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING) { mControllerTransportControls.pause(); } super.onPause(); }
If the activity stops, stop playback and unregister the media controller callback
@Override protected void onStop() { mController.unregisterCallback(mControllerCallback); if(mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING || mController.getPlaybackState().getState() == PlaybackStateCompat.STATE_PAUSED) { mControllerTransportControls.stop(); } super.onStop(); }
When the activity starts set the playback state to capability to play and register the media controller callback
@Override protected void onStart() { super.onStart(); mPlaybackStateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE); mSession.setPlaybackState(mPlaybackStateBuilder.build()); mController.registerCallback(mControllerCallback); }
Release the media controller callback when the activity is destroyed
@Override protected void onDestroy() { super.onDestroy(); mSession.release(); }
Change the default icon for the media button
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@mipmap/ic_media_play" android:id="@+id/videoPlayPauseButton" android:onClick="playPauseClick" app:layout_constraintRight_toRightOf="@+id/videoSurfaceView" android:layout_marginTop="24dp" app:layout_constraintTop_toBottomOf="@+id/videoSurfaceView" app:layout_constraintLeft_toLeftOf="@+id/videoSurfaceView" />
Android media viewer mediaplayer MediaControllerCompat summary
This completes the android media viewer mediaplayer mediacontrollercompat explanation. Hopefully this tutorial and the pervious MediaSession tutorial tutorial help to explain the roles of MediaSessionCompat and MediaControllerCompat. And how they provide the flexibility for the application to select UI or media player.