2

I'm trying to create a notification that uses the media button actions, but how do I send and receive those buttons? Here is what I have so far...

if(mediaSession==null) {
            mediaSession = new MediaSession(this, "Boom");
        }
        //Album art
        ImageView img = (ImageView)findViewById(R.id.img_AlbumArt1);
        Bitmap bitmap = ((BitmapDrawable)img.getDrawable()).getBitmap();

        PendingIntent mPauseIntent = PendingIntent.getBroadcast(this, 0,
                    new Intent(ACTION_PAUSE).setPackage(this.getPackageName()),
                    PendingIntent.FLAG_CANCEL_CURRENT);

        Notification.Builder mBuilder =
            new Notification.Builder(this)
                .setVisibility(Notification.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.ic_media_play)
                .setLargeIcon(bitmap)
                .setContentTitle(playingTitle)
                .setContentText(playingArtist)

                .setStyle(new Notification.MediaStyle()
                        .setMediaSession(mediaSession.getSessionToken())
                        .setShowActionsInCompactView(0,1,2)
                )
                // Add media control buttons that invoke intents in your media service
                .addAction(R.drawable.ic_media_rew, "Previous", null) //#0
                .addAction(R.drawable.ic_media_pause, "Play/Pause", null) //#1
                .addAction(R.drawable.ic_media_ff, "Next", null) //#2 nextPendingIntent
            ;
        // Creates an explicit intent for an Activity in your app
        Intent intent = new Intent(this, Music.class);
        intent.setAction(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_APP_MUSIC);
        // Creates an explicit intent for an Activity in your app
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(this,PendingIntent.FLAG_CANCEL_CURRENT,intent,0);
        mBuilder.setContentIntent(pendingIntent);

        NotificationManager NotiMan=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // mId allows you to update the notification later on.
        NotiMan.notify(notification, mBuilder.build());

Android docs suggest a pendingIntent where I have set null temporarily, but I haven't been able to figure out how to make a PendingIntent for this purpose.

BroadcastReceiver:

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final CharSequence action = intent.getAction();
        if(action==ACTION_PAUSE) {
            //mTransportControls.pause();
            Log.i("ON RECEIVE", "ACTION_PAUSE");
        }
    }
};

And in onCreate:

IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_PAUSE);
this.registerReceiver(mMessageReceiver, filter);
Ael
  • 323
  • 4
  • 14

1 Answers1

1
  1. The PendingIntent needs to point to either a BroadcastReceiver or a service that can act on the specified request. For example with a BroadcastReceiver you would have a pending intent that looks like

    public static final String ACTION_PAUSE = "com.pkg.name.ACTION_PAUSE";
    
    mPauseIntent = PendingIntent.getBroadcast(mService, REQUEST_CODE,
            new Intent(ACTION_PAUSE).setPackage(pkg),
            PendingIntent.FLAG_CANCEL_CURRENT); 
    
  2. Next, register the action/pendingIntent

     .addAction(R.drawable.ic_media_pause, mContext.getString(R.string.label_previous), mPendingIntent);
    
  3. Finally you handle the action when the pendingIntent is triggered. Here you can choose to use MediaController.TransportControls to play/pause the action.

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            switch (action) {
              case ACTION_PAUSE:
                mTransportControls.pause();
                break;
            ...
        }
    
  4. The MediaSession should be instantiated and setup to act on the play/pause + other actions.

    mSession = new MediaSession(this, "Service");
    mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
             MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
    
  5. Finally extend the MediaSession.MediaSessionCallback and implement onPlay()/onPause().. which inturn would actually work on the playback.

Nagesh Susarla
  • 1,660
  • 10
  • 10
  • Excellent. This helped me get what I needed :) Updated my code with most of the added pieces. – Ael May 27 '15 at 13:32