从BroadcastReceiver接收数据时onReceive方法未被调用。

4

我有一个音乐应用程序,我想在通知栏上添加一些操作按钮。

我尝试了类似于这样的东西:

 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);

}

我在这个服务中声明了一个NotificationReceiver类。
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;
               }
           }
       }
    }
}

结构大致如下:

-MusicService extends Service 
    --NotificationReciever extends BroadcastReceiver

我的清单文件包含以下接收器:

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

当我运行我的音乐播放器时,通知会弹出带有按钮,但这些按钮似乎无法触发onReceive函数? 我错过了什么?
更新:
按照Hasif Sayed的回答,我似乎发现了一个错误。

java.lang.RuntimeException:无法实例化接收器com.example.tilak.imusicplay.MusicService $ NotificationReciev​​er:java.lang.InstantiationException:java.lang.Class没有零参数构造函数

通过谷歌搜索,我发现我必须使用静态类或在父类中注册/注销。
所以这就是我做的事情:
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);

现在我不再遇到上述错误,但是onReceive又不起作用了。

1
下面的问题和回答都很好。 - Anh Duy
1个回答

5
实际上,当您点击“暂停”,“上一首”和“下一首”按钮时,广播接收器未被调用的原因是因为您设置了待定意图以触发一个“活动”,而不是设置待定意图以触发一个“广播”。请使用以下代码片段:
PendingIntent nextPendingIntent=PendingIntent.getActivity
            (this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;

您需要像这样更正它

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

请修改您编写的三个待处理意图代码中的错误。

更新

您的广播接收器仍未接收到广播的原因是因为您以编程方式注册了您的接收器作为本地广播

使用PendingIntent时,本地广播将无法接收广播。

因此,请删除此行。

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"));

相反,你只需要在Manifest.xml文件中注册接收者

或者 你可以在代码中进行程序注册

NotificationReciever mReciever = new NotificationReciever();

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

但是如果你以程序方式注册该程序,请确保在服务被销毁时注销它。否则,你可能会泄露BroadcastReceiver对象。


java.lang.RuntimeException: 无法实例化接收器com.example.tilak.imusicplay.MusicService$NotificationReciever:java.lang.InstantiationException:java.lang.Class<com.example.tilak.imusicplay.MusicService$NotificationReciever>没有零参数构造函数。你有什么想法吗? - Tilak Raj
@BOTJr. 这个问题是因为你将BroadcastReciever声明为服务的内部类,当你将其声明为内部类时,你不能在manifest.xml文件中注册该接收器。 - Hasif Seyd
谢谢,它起作用了。请编辑您的代码。它包含太多的错别字。 - Tilak Raj
1
@BOTJr. 很高兴我能帮到你 :) - Hasif Seyd
1
非常好!它节省了我更多时间。当使用pendingIntent.getbroadcast()时,必须使用Intent().setAction("manifest中广播的action名称"),不要使用Intent(context, BroadcastName.class)。谢谢! - Anh Duy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接