为什么PendingIntent.getBroadcast()只能被静态接收器识别?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么PendingIntent.getBroadcast()只能被静态接收器识别?相关的知识,希望对你有一定的参考价值。

我正在使用FCM,在onMessageReceived()我使用PendingIntent.getBroadcast()来调用同一服务中的BroadcastReceiver。在下面的代码中,如果从通知托盘中删除通知,我将发送广播。

 @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

     ......

     Intent intent = new Intent(getApplicationContext(), MyBroadcastReceiver.class);
            intent.putExtra("id", NOTIFICATION_ID);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setDeleteIntent(pendingIntent);

     ......

}

此外,在onCreate()方法中,我正在注册BroadcastReceiver,因为我正在从其他一些活动发送广播。

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate: ");

    //  registering the broadcast receiver on action "broadcastReceiverAction"
    IntentFilter intentFilter = new IntentFilter("broadcastReceiverAction");
    LocalBroadcastManager.getInstance(this).registerReceiver(new MyBroadcastReceiver(), intentFilter);
}  

我观察到,在从清单中删除静态接收器时,尽管在BrodcastReceiver方法中注册了广播接收器,但onCreate()并没有被要求删除通知。为什么会这样?这是否意味着PendingIntent.getBroadcast()需要静态接收器?

MyBroadcastReceiver

public static class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences sharedPreferences = context.getSharedPreferences("shared", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(String.valueOf(intent.getExtras().getInt("id")));
        editor.commit();
    }
}

编辑1静态广播接收器

<receiver android:name=".MyFirebaseMessagingService$MyBroadcastReceiver"  android:exported="true">
        <intent-filter>
            <action android:name="broadcastReceiverAction" />
        </intent-filter>
    </receiver>

onDestroy()取消注册广播接收器

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy: ");

    //  un-registering receiver
    LocalBroadcastManager.getInstance(this).unregisterReceiver(new MyBroadcastReceiver());
}
答案

因为您使用动态广播(非静态)的代码不正确。

首先,您在onCreate方法注册

//  registering the broadcast receiver on action "broadcastReceiverAction"
IntentFilter intentFilter = new IntentFilter("broadcastReceiverAction");
LocalBroadcastManager.getInstance(this).registerReceiver(new MyBroadcastReceiver(), intentFilter);

然后你发一个广播

Intent intent = new Intent(getApplicationContext(), MyBroadcastReceiver.class);
intent.putExtra("id", NOTIFICATION_ID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

你忘了将action添加到由PendingIntent包含的意图中,这就是为什么系统无法找到并触发你的广播。

将您的代码更改为

Intent intent = new Intent(getApplicationContext(), MyBroadcastReceiver.class);
intent.setAction("broadcastReceiverAction"); // Add this line
intent.putExtra("id", NOTIFICATION_ID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

更新:当您删除通知时,PendingIntent将执行广播,如调用Context.sendBroadcast()。在您的代码中,您使用LocalBroadcastManager,它只捕获message/intent已从您的应用程序中的组件广播。它无法从系统中捕获message/intent

所以将代码更改为

private MyBroadcastReceiver myBroadcastReceiver;

@Override
public void onCreate() {
    super.onCreate();
    //  registering the broadcast receiver on action "broadcastReceiverAction"
    IntentFilter intentFilter = new IntentFilter("broadcastReceiverAction");
    myBroadcastReceiver = new MyBroadcastReceiver();
    registerReceiver(myBroadcastReceiver, intentFilter);
}

@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(myBroadcastReceiver);
}

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

     ......

     Intent intent = new Intent("broadcastReceiverAction");
     intent.putExtra("id", NOTIFICATION_ID);
     PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
     builder.setDeleteIntent(pendingIntent);

     ......

}

以上是关于为什么PendingIntent.getBroadcast()只能被静态接收器识别?的主要内容,如果未能解决你的问题,请参考以下文章

Redis 为什么面试都问我却不懂?因为它快吗?它为什么快?

CodeBlocks中这是为啥啊

为什么选择容器技术,又为什么选择了kubernetes?

Full GC为什么那么慢?为什么老年代垃圾回收效率比新生代低很多?为什么Minor gc速度比Major GC慢?

转载 JavaWeb项目为什么我们要放弃jsp?为什么要前后端解耦?为什么要动静分离?

如何回答「为什么想做产品经理」面试核心问题3