Search code examples
androidbroadcastreceiverandroid-notificationsnotification-action

BroadcastReceiver context registration not working


I'm working on a project where I need to register a BroadcastReceiver and send a broadcast to it from a Notification Action. Please tell me if there is something glaring that I'm doing wrong. I don't want the receiver to be registered in the manifest because I want to have the custom onRecieve method that accesses several local variables.

Full Code available here: https://github.com/akirby/notificationTest

Edit: According to the Android documentation (https://developer.android.com/guide/components/broadcasts.html), this is possible, but I'm having trouble understanding why this is not working.

BroadcastReciever local variable

public BroadcastReceiver approveReceiver = new BroadcastReceiver(){
    @Override
    public void onReceive(Context context, Intent intent){
        notificationManager.cancel(notificationId);
        String data = intent.getAction();
        Toast.makeText(getApplicationContext(), data, Toast.LENGTH_LONG);
        if(data != null && data.equals("com.myapp.Approve")){
            mainText.setText("Approved");
        }
        else{
            mainText.setText("Denied");
        }
    }
};

Registration:

registerReceiver(approveReceiver, new IntentFilter("com.myapp.Approve"));

Notification:

public void showNotification(){

    Context appContext = getApplicationContext();
    Intent approveIntent = new Intent(appContext, ApprovalReceiver.class);
    approveIntent.setData(Uri.parse("Approve"));
    approveIntent.setAction("com.myapp.Approve");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(appContext, 0, approveIntent, PendingIntent.FLAG_CANCEL_CURRENT);

    Intent denyIntent = new Intent(appContext, ApprovalReceiver.class);
    approveIntent.setData(Uri.parse("deny"));
    denyIntent.setAction("com.myapp.Deny");
    PendingIntent denyPendingIntent = PendingIntent.getBroadcast(appContext, 0, denyIntent, PendingIntent.FLAG_CANCEL_CURRENT);


    NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("Test Notification")
            .setContentText("Test notification details")
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .addAction(R.drawable.ic_launcher_foreground, getString(R.string.Approved),
                    pendingIntent)
            .addAction(R.drawable.ic_launcher_foreground, getString(R.string.Deny),
                    denyPendingIntent);
    notificationManager.notify(notificationId, builder.build());
}

Solution

  • I figured out my problem. It was a conflict with how i was instantiating the Intent objects and my IntentFilter objects. The IntentFilters were being instantiated with an action, and while I was instantiating the Intents with a ".setAction" option, the fix is below:

    Change this:

    Intent approveIntent = new Intent(appContext, ApprovalReceiver.class);
    

    To this:

    Intent approveIntent = new Intent("com.myapp.Approve");
    

    because my IntentFilter for the BroadcastReceiver registration is as such:

    this.registerReceiver(approveReceiver, new IntentFilter("com.myapp.Approve"));