1

I am working on an Android application which is basically a music app. According to one of the requirements when a song plays in the music player, a notification should also appear in the notification bar, which can also be seen when the device is locked. Now I have created a custom layout for the notification which has some buttons to interact with the music player. I can see the notification when the song plays but I'm not able to handle their clicks. I have created a BroadcastReceiver too. I have searched on SO for this, Googled it and applied many solutions given there but still i'm not able to handle it.I even went through this video to do it but in vain till now: How To Create Custom Notification in Android

I'm pasting my code here, please let me know where i'm doing it wrong.

Notification UI is as follows: Notification

This is the method to set the notification.

public void setNotification(String songName,final String image,String songNamear){
    String ns = Context.NOTIFICATION_SERVICE;
    notificationManager = (NotificationManager) getSystemService(ns);

    Thread th=new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                URL url = new URL(image);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 8;
                image12 = BitmapFactory.decodeStream(input, null, options);
                BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(input, false);
                image12 = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);
            } catch(IOException e) {
                System.out.println(e);
            }
        }
    });
    th.start();
    Notification.Builder mNotifyBuilder = new Notification.Builder(this);
    notification = mNotifyBuilder.setContentTitle(songName)
            .setContentText(songNamear)
            .setSmallIcon(R.drawable.app_icon)
            .setLargeIcon(image12)
            .build();
    mNotifyBuilder.setPriority(Notification.PRIORITY_HIGH);

    notificationView = new RemoteViews(getPackageName(), R.layout.notification_mediacontroller);
    notificationView.setImageViewResource(R.id.btn_play_pause_in_notification,R.drawable.home_stop_icon);
    Log.d("imageuri",""+Uri.parse(image));
    notificationView.setImageViewBitmap(R.id.img_user,image12);
    notificationView.setTextViewText(R.id.txt_songname,songName);
    notificationView.setTextViewText(R.id.txt_songnamear,songNamear);
    SharedPreferences.Editor editor = getSharedPreferences("juke1", MODE_PRIVATE).edit();
    editor.putString("pos",""+intPOs);
    editor.commit();
    Intent notificationIntent = new Intent(this, MusicPlayerActivity.class);
    notificationIntent.putExtra("Position",intPOs);
    notificationIntent.putExtra("page","not");
    PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.contentView = notificationView;
    notification.contentIntent = pendingNotificationIntent;
    notification.flags |= Notification.FLAG_NO_CLEAR;
    
    //this is the intent that is supposed to be called when the button is clicked

    Intent switchIntent = new Intent(Constants.NOTIFICATION_CLICK_ACTION);
    switchIntent.setAction(Constants.ACTION_PLAY);
    PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(MusicPlayerActivity.this, 100, switchIntent, 0);

    Intent switchIntent1 = new Intent(Constants.NOTIFICATION_CLICK_ACTION);
    switchIntent1.setAction(Constants.ACTION_NEXT);
    PendingIntent pendingSwitchIntent1 = PendingIntent.getBroadcast(MusicPlayerActivity.this, 101, switchIntent1, 0);

    Intent switchIntent2 = new Intent(Constants.NOTIFICATION_CLICK_ACTION);
    switchIntent2.setAction(Constants.ACTION_PREV);
    PendingIntent pendingSwitchIntent2 = PendingIntent.getBroadcast(MusicPlayerActivity.this, 102, switchIntent2, 0);

    Intent switchIntent3 = new Intent(Constants.NOTIFICATION_CLICK_ACTION);
    switchIntent3.setAction(Constants.ACTION_CLOSE);
    PendingIntent pendingSwitchIntent3 = PendingIntent.getBroadcast(MusicPlayerActivity.this, 103, switchIntent3, 0);

    notificationView.setOnClickPendingIntent(R.id.btn_play_pause_in_notification, pendingSwitchIntent);
    notificationView.setOnClickPendingIntent(R.id.btn_next, pendingSwitchIntent1);
    notificationView.setOnClickPendingIntent(R.id.btn_prev, pendingSwitchIntent2);
    notificationView.setOnClickPendingIntent(R.id.btn_close, pendingSwitchIntent3);
    notificationManager.notify(1, notification);

Following is the BroadcastReceiver. I tried it it separate class as well as as inner class of MusicPlayerActivity. With inner class i will be easy call the functions for next song, previous song, play/pause etc for which buttons clicks are intended.

public class NotificationListener extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        MakeToast.show("Clcik");
        String action = intent.getAction();
        if(action.equalsIgnoreCase(Constants.ACTION_NEXT)){
            MakeToast.show("Next");
        }
        if(action.equalsIgnoreCase(Constants.ACTION_PREV)){
            MakeToast.show("Previous");
        }
        if(action.equalsIgnoreCase(Constants.ACTION_CLOSE)){
            MakeToast.show("Close");
        }
        if(action.equalsIgnoreCase(Constants.ACTION_PLAY)){
            MakeToast.show("Play");
        }

    }
}

In Android Manifest, receiver is declared as following. At the moment it is in separate class.

<receiver android:name=".listeners.NotificationListener">
        <intent-filter>
            <action android:name="notification_button_clicked" />
        </intent-filter>
    </receiver>

Any help would be appreciated regarding it as i'm very late behind my schedule.

Thanks

Community
  • 1
  • 1
Harry .Naeem
  • 1,245
  • 3
  • 20
  • 33

1 Answers1

0

You can use a service class for handle button clicks via notification remote view.

public class MusicPlayerService extends Service {
public static final String ACTION_PAUSE_PLAY = PACKAGE_NAME + ".playpause";
public static final String ACTION_NEXT = PACKAGE_NAME + ".next";
public static final String ACTION_PREVIOUS = PACKAGE_NAME + ".prev";


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null && intent.getAction() != null) {

        switch (intent.getAction()) {
            case ACTION_PREVIOUS:
                // go to previous song
                break;
            case ACTION_NEXT:
                // go to next song
                break;
            case ACTION_PAUSE_PLAY:
                // pause or play song
                break;
        }
    }
    return START_NOT_STICKY;
}

Also you must link notification buttons with pending intent

 PendingIntent pendingIntent;

    final ComponentName serviceName = new ComponentName(service, MusicPlayerService.class);

    // Previous track
    pendingIntent = buildPendingIntent(service, ACTION_PREVIOUS, serviceName);
    notificationLayout.setOnClickPendingIntent(R.id.prev, pendingIntent);

    // Play and pause
    pendingIntent = buildPendingIntent(service, ACTION_PAUSE_PLAY, serviceName);
    notificationLayout.setOnClickPendingIntent(R.id.playpause, pendingIntent);

    // Next track
    pendingIntent = buildPendingIntent(service, ACTION_NEXT, serviceName);
    notificationLayout.setOnClickPendingIntent(R.id.next, pendingIntent);
twenk11k
  • 557
  • 5
  • 17