Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onReceive from BroadcastReceiver is not called

I have a music application in which I am trying to add some action button on the notification bar.

I tried something like this:

 public void onPrepared(MediaPlayer mediaPlayer) {
    mediaPlayer.start();
    Intent onPreparedIntent=new Intent("MEDIA_PLAYER_PREPARED").putExtra("CURR_SONG",songposn);
    LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent);
    Intent notintent = new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    Notification.Builder builder=new Notification.Builder(this);
    PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notintent,PendingIntent.FLAG_UPDATE_CURRENT);
    PendingIntent prevPendingIntent=PendingIntent.getActivity
            (this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
    PendingIntent pausePendingIntent=PendingIntent.getActivity
            (this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
    PendingIntent nextPendingIntent=PendingIntent.getActivity
            (this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
    builder.setContentIntent(pendingIntent).setSmallIcon(R.drawable.playicon)
            .addAction(R.drawable.back, "Previous", prevPendingIntent)
            .addAction(R.drawable.playsmall, "Pause", pausePendingIntent)
            .addAction(R.drawable.forw, "Next", nextPendingIntent)
            .setTicker(songArtist)
            .setOngoing(true).setContentTitle(songTitle).setContentText(songArtist);

    Notification not=builder.build();
    startForeground(MusicService.NOTIFY_ID,not);

}

I declared a NotificationReciever class inside this service

public class NotificationReciever extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("here","here");
       String action=intent.getAction();
       if(action!=null){
           switch (action){
               case "PREVIOUS":{
                   playPrev();
                   break;
               }
               case "PAUSE":{
                   pausePlayer();
                   LocalBroadcastManager.getInstance(MusicService.this).sendBroadcast(new Intent("STOP_THREAD"));
                   break;
               }
               case "NEXT":{
                   playNext();
                   break;
               }
           }
       }
    }
}

Structure looks something like this:

-MusicService extends Service 
    --NotificationReciever extends BroadcastReceiver

My manifest file contains reciever like this:

 <receiver  android:name=".MusicService$NotificationReciever">
        <intent-filter>
            <action android:name="PREVIOUS"/>
            <action android:name="PAUSE"/>
            <action android:name="NEXT"/>
        </intent-filter>
    </receiver>

When I run my music play, notification does come up with buttons but they don't seem to fire the onReceive function?

What am I missing here?

Update:

Followed hasif sayed answer and I seem to found an error

java.lang.RuntimeException: Unable to instantiate receiver com.example.tilak.imusicplay.MusicService$NotificationReciev‌​er: java.lang.InstantiationException:java.lang.Class has no zero argument constructor

Googling about it, I found that I have to use a static class or I have to register/unregister in the parent class.

So this is what I did:

public void onCreate() {
        super.onCreate();
        //
        LocalBroadcastManager.getInstance(this).registerReceiver(
                new NotificationReciever(),new IntentFilter("PREVIOUS"));
        LocalBroadcastManager.getInstance(this).registerReceiver(
                new NotificationReciever(),new IntentFilter("PAUSE"));
        LocalBroadcastManager.getInstance(this).registerReceiver(
                new NotificationReciever(),new IntentFilter("NEXT"));
    }

PendingIntent prevPendingIntent=PendingIntent.getBroadcast
                (this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pausePendingIntent=PendingIntent.getBroadcast
                (this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent nextPendingIntent=PendingIntent.getBroadcast
                (this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);

Now I don't get this above error but onReceive is not working again.

like image 911
Tilak Raj Avatar asked Sep 17 '25 04:09

Tilak Raj


1 Answers

Actually the reason why your broadcast reciever is not called when you click on pause,previous and next button is because ,you have set the pending intent to fire an acitivity,instead you have to set the pending intent to fire a boradcast

instead of this code snippet

PendingIntent nextPendingIntent=PendingIntent.getActivity
            (this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;

you have to correct it like this

PendingIntent nextPendingIntent=PendingIntent.getBroadcast
            (this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;

make corrections in all the three pending intent code which you have written

UPDATE

The reason why you still not receiving the broadcast in your Broadcast Receiver is because you are programitically registering your Receiver as LocalBroadCast

When using with PendingIntent, LocalBroadcast will not receive the Broadcast

so please remove this Line

LocalBroadcastManager.getInstance(this).registerReceiver(
                new NotificationReciever(),new IntentFilter("PREVIOUS"));
        LocalBroadcastManager.getInstance(this).registerReceiver(
                new NotificationReciever(),new IntentFilter("PAUSE"));
        LocalBroadcastManager.getInstance(this).registerReceiver(
                new NotificationReciever(),new IntentFilter("NEXT"));

Instead, you only have to register the receiver in the Manifest.xml file

or programitically you can register in code as

NotificationReciever mReciever = new NotificationReciever();

this.registerReceiver(
                mReciever,new IntentFilter("PREVIOUS"));
this.registerReceiver(
                mReciever,new IntentFilter("PAUSE"));
this.registerReceiver(
                mReciever,new IntentFilter("NEXT"));

but if you register this programitically, make sure you unregister it while service is getting destroyed. Otherwise you may LEAK the BroadcastReceiver Object

like image 173
Hasif Seyd Avatar answered Sep 19 '25 17:09

Hasif Seyd