【问题标题】:Dismiss notification from BroadCastReceiver关闭来自 BroadCastReceiver 的通知
【发布时间】:2014-08-13 19:10:07
【问题描述】:

我在一个 Android 应用程序的主要 Activity 中有一个子类 BroadCastReceiver,用于处理 GCM 进入时更改 GUI。所有这些都可以正常工作。

不起作用的一件事是,如果它被调用,那么用户在他的设备上打开了我的应用程序,因此我想清除我为这个传入的 GCM 进入通知中心的通知。如果我将 cancelAll() 和 cancel(int) 行放入我的 GCMIntentService 中,那么它会关闭通知,但我不能将其保留在那里,因为我只想在用户打开我的应用程序时关闭此通知。我同时使用了 cancel() 和 cancelAll() 来确保我没有以某种方式从 IntentService 传递错误的通知 id(我已经验证它是正确的)。

问题是没有错误,通知中心的通知根本不会消失。自从我在 logcat 中获取日志条目以来,我已经验证了此方法正在被调用。

我引用了这个先前的答案,但由于某种原因它在我的实现中不起作用:Starting and stopping a notification from broadcast receiver

我的主要活动中的代码:

private class NotificationBroadcastReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    Log.v("Push", "Received Push Notification!");

    //Now that the user has opened the app, cancel the notification in the notification center if it is still there
    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    final int NOTIFICATION_ID = intent.getIntExtra("notificationId",0);

    Log.v("NOTIFICATION_ID",Integer.toString(NOTIFICATION_ID));

    mNotificationManager.cancel(NOTIFICATION_ID);
    mNotificationManager.cancelAll();

    Log.v("Canceled Notifs","Canceled");
  }
} 

有什么想法吗?

【问题讨论】:

  • 首先在cancellAll 之后放置一个日志,检查您是否在那里获取日志。其次,您是否在其他设备上尝试过该场景?
  • 添加了它,这是一个成绩单:08-13 12:40:45.387: I/Push Notification(30615): Completed work @ 826126803\r\n 08-13 12:40:45.387: V/Push(30615):收到推送通知! 08-13 12:40:45.387: V/NOTIFICATION_ID(30615): 1 08-13 12:40:45.387: V/取消通知(30615): 取消
  • 我还没有在其他设备上尝试过 - 这真的是设备问题吗?我的测试是在运行 API 版本 20 os 4.4 kitkat 的新 Nexus 5 上完成的
  • 一种可能性是您在关闭之前的通知后立即在应用程序的其他部分触发了另一个通知。

标签: android notifications broadcastreceiver google-cloud-messaging


【解决方案1】:

一个可能更好的选择是,不是在应用打开时发布通知,而是首先检测应用是否可见,如果是,则不显示通知。您可以使用 Intent 广播或 EventBus 或 Otto 等事件总线来执行此操作。

例子:

public class GCMReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // this is your receiver after gcm has been received 
        Intent appOpenCheck = new Intent("com.example.IS_APP_OPEN");
        // put extras about your notification here...
        context.sendOrderedBroadcast(appOpenCheck);
    }
}

public class AppNotOpenReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // this is your receiver that will be hit if the app isn't open 
        // post your notification to the NotificationManager
    }
}

然后,在AndroidManifext.xml

<receiver
    android:name=".AppNotOpenReceiver">
         <intent-filter>
            <action android:name="com.example.IS_APP_OPEN" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
</receiver>

最后,在你的Activity

BroadcastReceiver appOpenAlert = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        abortBroadcast(); // prevents notification from going further
        // this is your receiver that will be hit if the app is open 
        // update your ui
    }
}

@Override
public void onStart() {
    super.onStart();
    IntentFilter notificationReceived = new IntentFilter();
    notificationReceived.addAction("com.example.IS_APP_OPEN");
    notificationReceived.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    registerReceiver(appOpenAlert, notificationReceived);
}

@Override
public void onStop() {
    unregisterReceiver(appOpenAlert);
    super.onStop();
}

【讨论】:

  • 对于任何找到此答案的人 - 我能够按照说明进行操作,只需进行一些小改动。主要的一个是在主应用程序中将接收器的优先级设置为高于“AppNotOpen”接收器后,您必须在主应用程序接收器中包含对 abortBroadcast() 的调用,否则它将传播到“AppNotOpen”之后主应用程序中的接收器根据订购的广播处理它,并且仍会添加不需要的通知。
  • 我刚刚注意到我错过了在您的原始回复中对 abortBroadcast() 的调用,sddamico。很好的解决方案,再次感谢!
  • 认为我可能在原始帖子之后更新以添加该内容,但无论如何,很高兴我能提供帮助。这个问题我已经处理过几次了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 2022-06-10
相关资源
最近更新 更多