Android BroadcastReceiver onReceive()在android 4.0上调用了两次

gir*_*dge 25 android broadcastreceiver

我遇到了android 4.0.3上的一个问题(在4.1.2上工作正常).我有我的Activity BroadcastReceiver.当我发送广播时,方法onReceive()总是被调用两次.请给我关于4.0和4.1的BroadcastReceiver差异的任何建议

private final GcmBroadcastReceiver gcmReceiver = new GcmBroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (action != null && action.equals(MyBroadcastReceiver.ACTION)) {
            Log.d("tag", intent.getStringExtra("alert"));
            }
        }
    };

};


@Override
protected void onPause() {
    unregisterReceiver(gcmReceiver);
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    registerGcmReceiver();
}

private void registerGcmReceiver() {
    IntentFilter filter = new IntentFilter(MyBroadcastReceiver.ACTION);
    filter.setPriority(2);
    filter.addCategory("com.android.mypackage");
    registerReceiver(gcmReceiver, filter);
}
Run Code Online (Sandbox Code Playgroud)

Mer*_*ury 40

通常onReceive被调用两次,因为人们在两个位置注册广播, 很可能你在onCreate和onResume中注册. (选择一个注册地点).

虽然你可能已经做过十几次了 - 但总是建议再看一下活动生命周期.


Sus*_*ant 21

我有同样的问题.

onReceive()因为我两次注册广播接收器而被叫两次.一个在我的活动中onCreate(),另一个在manifest.

我删除广播接收器注册onCreate(),它工作正常.只在其中一个中注册您的广播接收器.

有两种方法可以做到这一点:

  • 静态地在清单文件中.
  • 动态地在代码中.

使用哪种方法(静态或动态)完全取决于您尝试做什么.基本上当你想通过在系统范围的事件或其他应用程序发送的事件中显示状态栏中的一些通知或某些指示器时,在屏幕上(主屏幕,启动器,状态栏等)进行一些更改,那么使用静态注册的广播接收器是有意义的.然而,基于类似的事件,您希望在用户使用它时在应用程序中进行更改,或者可能将其放在后台,那么使用动态注册的接收器是有意义的,这些接收器将持续到注册组件被销毁.

欲了解更多信息:http: //codetheory.in/android-broadcast-receivers/


npa*_*ace 10

简短回答:没有区别.这BroadcastReceiver两个类都来自Android 2.3.2 r1.

我有一个类似的问题,但对我来说,它是搭配Android 2.3.5的HTC Desire HD - 来自GCM的通知总是会收到两次.我没有设法找到问题的根源,但有一个解决方法.您可以为服务器中的每个通知生成唯一ID,并将其与实际数据一起发送.然后,在您的接收器中,您可以更新唯一ID到通知数据的映射,如果已经有给定ID的数据,则忽略它.

我可能没有说清楚,所以这是一个例子:

public void onReceive(Context context, Intent intent) {
    String id = intent.getStringExtra("notificationID");
    if (myMap.get(id) != null)
        return;

    final String action = intent.getAction();
    if (action != null && action.equals(MyBroadcastReceiver.ACTION)) {
        Log.d("tag", intent.getStringExtra("alert"));
        myMap.put(id, *any value you need*);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不需要存储其他数据,则可以使用HashSet而不是Map,并检查它是否包含ID.


小智 8

Inatialize BroadcastReciveron onStart().这解决了我的问题.