【问题标题】:AlarmManager won't stop after the app is restarted应用重启后AlarmManager不会停止
【发布时间】:2014-10-25 17:08:48
【问题描述】:

我已经实现了警报管理器,就像它在 Google 示例应用中实现的一样。一切正常,除非我重新启动应用程序,警报管理器将不再停止。

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

所以这就是问题所在。当我第一次运行应用程序并启动 AlarmManager 时,我可以轻松地停止它。但是一旦我关闭应用程序并再次运行它,AlarmManager 就不能再停止了。当我按下停止按钮时,什么也没有发生。

我几乎 100% 确定原因是应用程序重启后 AlarmManager 为空。但是如果我删除 if 语句,应用程序就会崩溃。

但是为什么这应该在示例应用程序中有效,但在我的应用程序中无效?

【问题讨论】:

  • 我遇到了同样的问题,我的闹钟在手机重启后没有重新启动我已经设置了 2 分钟的闹钟,如果在这段时间设备重启闹钟没有触发我在不同的片段中有超过 30 个不同的闹钟,所以请帮助我。

标签: android alarmmanager


【解决方案1】:

我通过像这样更改 cancelAlarm 方法来解决我的问题:

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

【讨论】:

    【解决方案2】:

    当我按下停止按钮时什么都没有发生。

    您问题的代码中没有“停止按钮”。

    我几乎 100% 确定原因是应用重启后 AlarmManager 为空

    我不知道“应用重启”是什么意思。

    但是您使用的是WakefulBroadcastReceiver。清单注册 BroadcastReceiver 上的数据成员是严重的代码异味。这样一个BroadcastReceiver 的实例将只存在一次对onReceive() 的调用。下一次广播将创建一个新实例,依此类推。因此,一旦onReceive() 结束,这些数据成员将毫无用处。

    因此,我强烈建议您删除:

    AlarmManager alarmManager;
    PendingIntent alarmIntent;
    

    这应该可以解决您的AlarmManager-is-null 问题。

    【讨论】: