Lock Screen Notifications In Android 5.0

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 🙂

lock1

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:

lock2

This is how you can manage your app’s lock screen notification. Checkout my previous blog on How to implement Rate this App feature

Leave a Comment: