Android Lollipop is running with new features, and one of those is locked screen notifications. Up until this point, lock screen media controls must be defined by the use of a RemoteView, and media control notifications must be built using custom views. Today in this exercise we will see how to use the new MediaStyle for notifications and interacting with a MediaSession for controlling media playback status.
Check the video below which google help has published to show how to change what notifications show up on your lock screen with Android Lollipop.
Let’s now check it with a code sample. Follow the steps below:
Step1: Create a new android project in you Android IDE.
Step2: Write following into your manifest. We will add Media_Content_Control permission to access media style:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.lockscreennotification" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MediaPlayerService" /> </application> <permission android:name="android.permission.MEDIA_CONTENT_CONTROL" /> </manifest>
Step3: Create a new class and write following into it. We will need a service to send messages to media player.
package com.example.lockscreennotification; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.media.Rating; import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.os.IBinder; import android.util.Log; public class MediaPlayerService extends Service { public static final String ACTION_PLAY = "action_play"; public static final String ACTION_PAUSE = "action_pause"; public static final String ACTION_REWIND = "action_rewind"; public static final String ACTION_FAST_FORWARD = "action_fast_foward"; public static final String ACTION_NEXT = "action_next"; public static final String ACTION_PREVIOUS = "action_previous"; public static final String ACTION_STOP = "action_stop"; private MediaPlayer mMediaPlayer; private MediaSessionManager mManager; private MediaSession mSession; private MediaController mController; @Override public IBinder onBind(Intent intent) { return null; } private void handleIntent( Intent intent ) { if( intent == null || intent.getAction() == null ) return; String action = intent.getAction(); if( action.equalsIgnoreCase( ACTION_PLAY ) ) { mController.getTransportControls().play(); } else if( action.equalsIgnoreCase( ACTION_PAUSE ) ) { mController.getTransportControls().pause(); } else if( action.equalsIgnoreCase( ACTION_FAST_FORWARD ) ) { mController.getTransportControls().fastForward(); } else if( action.equalsIgnoreCase( ACTION_REWIND ) ) { mController.getTransportControls().rewind(); } else if( action.equalsIgnoreCase( ACTION_PREVIOUS ) ) { mController.getTransportControls().skipToPrevious(); } else if( action.equalsIgnoreCase( ACTION_NEXT ) ) { mController.getTransportControls().skipToNext(); } else if( action.equalsIgnoreCase( ACTION_STOP ) ) { mController.getTransportControls().stop(); } } private Notification.Action generateAction( int icon, String title, String intentAction ) { Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class ); intent.setAction( intentAction ); PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0); return new Notification.Action.Builder( icon, title, pendingIntent ).build(); } private void buildNotification( Notification.Action action ) { Notification.MediaStyle style = new Notification.MediaStyle(); Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class ); intent.setAction( ACTION_STOP ); PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0); Notification.Builder builder = new Notification.Builder( this ) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle( "Lock Screen Media example Service" ) .setContentText( "Artist Name" ) .setDeleteIntent( pendingIntent ) .setStyle(style); builder.addAction( generateAction( android.R.drawable.ic_media_previous, "Previous", ACTION_PREVIOUS ) ); builder.addAction( generateAction( android.R.drawable.ic_media_rew, "Rewind", ACTION_REWIND ) ); builder.addAction( action ); builder.addAction( generateAction( android.R.drawable.ic_media_ff, "Fast Foward", ACTION_FAST_FORWARD ) ); builder.addAction( generateAction( android.R.drawable.ic_media_next, "Next", ACTION_NEXT ) ); style.setShowActionsInCompactView(0,1,2,3,4); NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE ); notificationManager.notify( 1, builder.build() ); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if( mManager == null ) { initMediaSessions(); } handleIntent( intent ); return super.onStartCommand(intent, flags, startId); } private void initMediaSessions() { mMediaPlayer = new MediaPlayer(); mSession = new MediaSession(getApplicationContext(), "simple player session"); mController =new MediaController(getApplicationContext(), mSession.getSessionToken()); mSession.setCallback(new MediaSession.Callback(){ @Override public void onPlay() { super.onPlay(); Log.e( "MediaPlayerService", "onPlay"); buildNotification( generateAction( android.R.drawable.ic_media_pause, "Pause", ACTION_PAUSE ) ); } @Override public void onPause() { super.onPause(); Log.e( "MediaPlayerService", "onPause"); buildNotification(generateAction(android.R.drawable.ic_media_play, "Play", ACTION_PLAY)); } @Override public void onSkipToNext() { super.onSkipToNext(); Log.e( "MediaPlayerService", "onSkipToNext"); //Change media here buildNotification( generateAction( android.R.drawable.ic_media_pause, "Pause", ACTION_PAUSE ) ); } @Override public void onSkipToPrevious() { super.onSkipToPrevious(); Log.e( "MediaPlayerService", "onSkipToPrevious"); //Change media here buildNotification( generateAction( android.R.drawable.ic_media_pause, "Pause", ACTION_PAUSE ) ); } @Override public void onFastForward() { super.onFastForward(); Log.e( "MediaPlayerService", "onFastForward"); //Manipulate current media here } @Override public void onRewind() { super.onRewind(); Log.e( "MediaPlayerService", "onRewind"); //Manipulate current media here } @Override public void onStop() { super.onStop(); Log.e( "MediaPlayerService", "onStop"); //Stop media player here NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancel( 1 ); Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class ); stopService( intent ); } @Override public void onSeekTo(long pos) { super.onSeekTo(pos); } @Override public void onSetRating(Rating rating) { super.onSetRating(rating); } } ); } @Override public boolean onUnbind(Intent intent) { mSession.release(); return super.onUnbind(intent); } }
Step4: Write following into main activity:
package com.example.lockscreennotification; import android.content.Intent; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class ); intent.setAction( MediaPlayerService.ACTION_PLAY ); startService( intent ); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
Step5: Make sure to set your minSDK to API 21 other wise this won’t run.
Step6: Run for output like below:
Thanks 🙂
If you won’t be able to check the output on your emulator’s lock screen don’t wary.. you will get a notification on notification bar like below:
This is how you can manage your app’s lock screen notification. Checkout my previous blog on How to implement Rate this App feature
Top 15 Best Android Apps For C Programming | 2018 Exclusive
Android Studio Introduction
Applying MediaCodec On An Open Source Android Audio Player
5 Most Used Android Testing Frameworks
Extracting Colors In Android 5.0 – “The Palette API”
Animations In Android KitKat
The Android Studio – An Introduction With The HelloWorld App
Recycler And CardView Combined In Android L