Guy
Guy

Reputation: 6522

AlarmManager won't stop after the app is restarted

I've implemented Alarm Manager just as it is implemented in the Google sample app. Everything works correct except if I restart the app, the Alarm Manager won't stop anymore.

AlarmReceiver.class

public class AlarmReceiver extends WakefulBroadcastReceiver {

AlarmManager alarmManager;
PendingIntent alarmIntent;


@Override
public void onReceive(Context context, Intent intent) {
    // do stuff here
}

public void setAlarm(Context context)
{
    alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, AlarmReceiver.class), 0);

    // Fire alarm every 30min
    alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
            5000,
            5000,
            alarmIntent);

    // Restart alarm if device is rebooted
    ComponentName receiver = new ComponentName(context, BootReceiver.class);
    PackageManager pm = context.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
}

public void cancelAlarm(Context context)
{
    if (alarmManager != null)
    {
        alarmManager.cancel(alarmIntent);
    }

    // Disable BootReceiver so that alarm won't start again if device is rebooted
    ComponentName receiver = new ComponentName(context, BootReceiver.class);
    PackageManager pm = context.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    }
}

So here's the problem. When I first run the app and start the AlarmManager, I can easily stop it. But once I close the app and run it again, the AlarmManager can't be stopped anymore. Nothing happens when I press the stop button at all.

I'm almost 100% sure that the reason is because AlarmManager is null after the app restart. But if I remove the if statement, the app crashes.

But then why does this supposedly work in sample app but not in my app?

Upvotes: 2

Views: 1028

Answers (2)

CommonsWare
CommonsWare

Reputation: 1006564

Nothing happens when I press the stop button at all.

There is no "stop button" in the code in your question.

I'm almost 100% sure that the reason is because AlarmManager is null after the app restart

I have no idea what "the app restart" means.

But you are using WakefulBroadcastReceiver. Data members on a manifest-registered BroadcastReceiver are a serious code smell. An instance of such a BroadcastReceiver will live for exactly one call to onReceive(). The next broadcast will create a new instance, and so on. Hence, those data members will be useless once onReceive() ends.

Hence, I strongly suggest that you remove:

AlarmManager alarmManager;
PendingIntent alarmIntent;

and that should clear up your AlarmManager-is-null problem.

Upvotes: 0

Guy
Guy

Reputation: 6522

I solver my problem by changing the cancelAlarm method like this:

public void cancelAlarm(Context context)
{
    alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, AlarmReceiver.class), 0);
    alarmManager.cancel(alarmIntent);

    // Disable BootReceiver so that alarm won't start again if device is rebooted
    ComponentName receiver = new ComponentName(context, BootReceiver.class);
    PackageManager pm = context.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
}

Upvotes: 2

Related Questions