Search code examples
androidandroid-intentnotificationsandroid-4.2-jelly-beanandroid-pendingintent

Android 4 and up, multi-action notifications


I want to use three actions buttons in a notification to control a media service and am having difficultly finding a working example of the code: Vogella has a tutorial but his uses a single button and opens an activity not a service. I have found several other tutorials and examples of this kind but none with three working action buttons that have similar tutorials that demonstrate the construction of intents for services and multiple actions, as well most current examples of action button usage on stackoverflow are either applicable to lower versions of android, use single intent buttons, ...

here is the code i am thinking of using to set up the notification:

//individual intents for each action???
Intent Back = new Intent(this, MusicService.class );
Back.putExtras("back", 1);
Back.putExtras("play", 0);
Back.putExtras("next", 0);

Intent Play = new Intent (this, MusicService.class);
Back.putExtras("back", 0);
Back.putExtras("play", 1);
Back.putExtras("next", 0);

Intent Next = new Intent (this, MusicService.class);
Next.putExtras("back", 0);
Next.putExtras("play", 0);
Next.putExtras("next", 1);


//do I need to make three pending intents????
PendingIntent pIntentback = PendingIntent.getService(this, 0, Back, 0);
PendingIntent pIntentplay = PendingIntent.getService(this, 0, Play, 0)
PendingIntent pIntentnext = PendingIntent.getService(this, 0, Next, 0)


Notification noti = new Notification.Builder(this)
.setContentTitle("Juke Box Hero")
.setContentText("Playing ")
.setSmallIcon(R.drawable.ic_launcher)
.addAction(R.drawable.back, "", pIntentback)
.addAction(R.drawable.play, "", pIntentplay)
.addAction(R.drawable.next, "", pIntentnext)
.build();

NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

noti.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);

I have several questions here...

1) is the above code how i should go about setting up the action buttons, intents, and pending intents?

2) since I want to recieve the intents wrapped by the pending intents in a service, am I correct in calling getService, instead of getActivity?

3) if I am able to recieve intents directly in the MusicService class, how can I receive the intents in the service without restarting the service (thus losing data stored in memory already)?

4) or do I need to build a receiver class to extend the BroadcastReceiver class and register that in the manifest and then send the corresponding intent to the MusicService class?

please understand that i am more than willing to research and write the code--and have been at that for several days before asking, but i am in need of straightforward answers to these questions...

help and direction are much appreciated


Solution

  • 1) is the above code how i should go about setting up the action buttons, intents, and pending intents?

    answer #1) no, in order to set up pending intents that fire and activate the appropriate activity or service the intent should have a setAction(insert your action name here) and the cooresponding pending intent should use an update current flag in the pending intent (see example code in answer to number 2 below)

    intents should look like this...

    Intent Play = new Intent (this, Receiver.class);
    Play.setAction("Play");
    Play.putExtra("back", 0);
    Play.putExtra("play", 1);
    Play.putExtra("next", 0);
    

    2) since I want to recieve the intents wrapped by the pending intents in a service, am I correct in calling getService, instead of getActivity?

    answer #2) no, i used a broadcastreciever class to catch the intents sent from the notification; it was neccessary to use getBroadcast and ensure that the application context (possibly not required, but seemed like a good idea) was attached in the following manner--

    PendingIntent pIntentback = PendingIntent.getBroadcast(this.getApplicationContext(), 0, Play, PendingIntent.FLAG_UPDATE_CURRENT);
    

    3) if I am able to recieve intents directly in the MusicService class, how can I receive the intents in the service without restarting the service (thus losing data stored in memory already)?

    answer #3) I avoided this question, but after some bit of research on the idea it seems that you can build a receiver inside a service class to handle this situation... i am unable at this time to give details on the effects and requirements of such, however the external broadcast reciever system i used does not interrupt the music service or reset information that was already passed through the original service intent...

    4) or do I need to build a receiver class to extend the BroadcastReceiver class and register that in the manifest and then send the corresponding intent to the MusicService class?

    answer #4) as noted above it is not a requirement to build a receiver class external to the service, but it seemed easiest to manipulate without causing damage to a perfectly functioning service class... individual intents within the reciever class were identified via the attached action keys and then action desired specific intents were built to send on to the service class...