BryanP
BryanP

Reputation: 710

Dismiss notification from BroadCastReceiver

I have a subclassed BroadCastReceiver inside my main activity in an android application to deal with changing the GUI when a GCM comes in. All of this works fine.

The one thing that doesn't work is that if this gets called then the user has my app open on his device, and as such I want to clear the notification I entered into the notification center for this incoming GCM. If I put the cancelAll() and cancel(int) lines into my GCMIntentService, then it dismisses the notifications, but I cannot keep it there since I only want to dismiss this notification if the user has my app open. I used both the cancel() and cancelAll() to make sure that I wasn't somehow passing the wrong notification id from the IntentService (I have verified it is correct).

The problem is that there is no error and the notification in the notification center simply won't go away. I have verified that this method is getting called since I get the log entries in logcat.

I referenced this prior answer, but it doesn't work in my implementation for some reason: Starting and stopping a notification from broadcast receiver

My code inside my main activity:

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

Any ideas why?

Upvotes: 2

Views: 4241

Answers (1)

sddamico
sddamico

Reputation: 2130

A potentially better option is, instead of posting the notification while the app is open, to first detect if the app is visible and, if it is, don't display the notification. You can do this using Intent broadcasts or an event bus like EventBus or Otto.

Example:

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
    }
}

Then, in 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>

Finally, in your 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();
}

Upvotes: 3

Related Questions