Search code examples
androidbroadcastreceiver

Dynamically registered BroadcastReceiver instance not firing?


I've been trying to find the problem here, but I can't seem to... my onReceive doesn't seem to get called, here's what I have:

public abstract class NoUpdatesTimer extends BroadcastReceiver {
    private Context context;
    private PendingIntent pendingIntent;

    public NoUpdatesTimer(Context context) {
        this.context = context;
        Intent intent = new Intent(Constants.ALARM_NO_LOC_UPDATES);
        pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        context.registerReceiver(this, new IntentFilter(Constants.ALARM_NO_LOC_UPDATES));
    }

    public void scheduleCheck(long delayMillis) {
        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delayMillis, pendingIntent);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        ...
    }
}

With some debugging, I verified that scheduleChecking is called but the onReceive method is not called. I also tried to trigger this code from a shell, using:

adb shell am broadcast -a rsg.ms.7

(where Constants.ALARM_NO_LOC_UPDATES is "rsg.ms.7").

Can you tell me what to change so onReceive gets called?


Solution

  • Using the application context instead of the passed in service context seems to make it work, not sure why:

    public abstract class NoUpdatesTimer extends BroadcastReceiver {
        private Context context;
        private PendingIntent pendingIntent;
    
        public NoUpdatesTimer(Context context) {
            this.context = context.getApplicationContext();
            Intent intent = new Intent(Constants.ALARM_NO_LOC_UPDATES);
            pendingIntent = PendingIntent.getBroadcast(this.context, 0, intent, 0);
            this.context.registerReceiver(this, new IntentFilter(Constants.ALARM_NO_LOC_UPDATES));
        }
    
        public void scheduleCheck(long delayMillis) {
            AlarmManager alarmManager = (AlarmManager)this.context.getSystemService(Context.ALARM_SERVICE);
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delayMillis, pendingIntent);
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            ...
        }
    }