【问题标题】:Android AlarmManager setRepeating doesn't repeat with long intervalAndroid AlarmManager setRepeating 不会长时间重复
【发布时间】:2011-09-02 18:37:02
【问题描述】:

我已实现 AlarmManager 每天唤醒手机一次以执行更新任务、更新小部件并在适用时发送通知。

我正在使用 setRepeatingELAPSED_REALTIME_WAKEUP 第一时间触发报警(SystemClock.elapsedRealtime()+60000) 但它不会在 86400000 毫秒(24 小时)后触发。

真的在为此苦苦挣扎,我很高兴接受我做错了什么,或者如果有更好的方法来实现我想要做的事情。但是我认为我的代码看起来像是人们似乎在做的标准事情。

这几乎就像重复警报在所有情况下都没有按照它所说的那样做。如果我将时间间隔缩短到 10 分钟,它确实有效,我的警报就会触发,并且服务会一遍又一遍地运行。

我的应用程序的性质意味着每天更新一次以上是多余的。 我需要为此找到一个现实可靠的解决方案。

感谢您的宝贵时间,希望您能指出正确的方向。

这是我的闹钟实现代码...

清单:

<receiver android:name=".SystemChangeReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" />
    </intent-filter>
</receiver>
<receiver android:name=".UpdateAlarmReceiver" />
<service android:name=".UpdateService" />
<receiver android:name=".WidgetProviderSmall" android:label="@string/widget_small_label">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/appwidget_small" />
</receiver>
<receiver android:name=".WidgetProviderLarge" android:label="@string/widget_large_label">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/appwidget_large" />
</receiver>

SystemChangeReceiver 监听开机广播,检查是否需要设置警报,如果需要,则设置。

SystemChangeReceiver:

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

    SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.prefs_name), 0);

    Boolean notifications = prefs.getBoolean("enable_updates", false);
    if(notifications == true) {
        Utils.setNotificationAlarm(context);
    }
}

setNotificationAlarm 方法,设置重复报警...

public static void setNotificationAlarm(Context context) {
        AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        Intent intent = new Intent(context, UpdateAlarmReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);

        alarmManager.setRepeating(
            AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime()+60000,
            86400000,
            pi);
}

当警报触发我的接收器UpdateAlarmReceiver 决定做什么并使用WakefulIntentService 运行我的后台更新过程时,服务的处理程序然后更新小部件并根据需要发送通知

UpdateAlarmReceiver:

public void onReceive(Context context, Intent intent) {
    WakefulIntentService.sendWakefulWork(context, UpdateService.class);
}

【问题讨论】:

  • 可以解决所有这些问题的快速问题:您使用任务杀手吗?您的应用是否在其白名单中?
  • 我实际上正在使用 AutoKiller Memory Optimizer 它没有白名单这可能是问题吗?根据进程列表,我的应用仍在运行。

标签: android alarmmanager


【解决方案1】:

没有什么明显的错误。

不过,在这样的很长一段时间内,我建议您使用RTC_WAKEUP,这样您就可以安排它在半夜或用户可选择的时间发生,而不是每 24 小时从半随机起点。 RTC_WAKEUP 可能会给您带来更好的结果。

还有:

  • UpdateAlarmReceiveronReceive() 中添加一条日志语句,以确认您是否获得了控制权,或者问题是否出在(喘气!)WakefulIntentService
  • 尝试稳步增加您的经期。既然你说 10 分钟有效,那就试试 1 小时,然后是 4 小时,以此类推,当它崩溃时,试着了解一下。
  • “我实际上正在使用 AutoKiller 内存优化器,它没有白名单,这可能是问题所在?我的应用程序仍在运行,尽管根据进程列表。” -- 我会禁用所有任务杀手,以确保它们不会干扰。

【讨论】:

  • 谢谢马克,我已经在各个地方添加了日志记录,很长一段时间内它甚至没有击中警报接收器,所以我很确定它的警报管理器在某个地方有问题。我现在禁用了内存优化器,我会尝试所有其他建议。
  • @Rob:我所知道的唯一可以消除预定警报的事情是:如果您 cancel() 它,如果用户从“设置”应用程序中的“管理服务”中强制停止它,或者如果任务杀手阻止它(这可能只是 2.1 和更早版本的问题——我不希望 killBackgroundProcesses() 消除警报,但我可能错了)。希望您会发现 AutoKiller 是罪魁祸首。
【解决方案2】:

您是否尝试过将其设置为不重复。然后,当它启动时,您将下一个单发警报设置为 24 小时后?这将起到重复警报的作用,但可能会避免您看到的一些问题。

【讨论】:

  • 我没有考虑过这个。我认为这基本上就是 setRepeating 所做的。不过我会试试的,谢谢。
  • 我做了一个闹钟类型的应用程序,这就是我处理它的方式,它似乎对我来说正确,提示 AlarmActivity 在第二天的正确时间启动。我从来没有使用过 setRepeating() 标志,所以我不确定为什么它不起作用,在我看来,这两种方法的功能应该相同。会不会是触发时没有正确唤醒设备?
  • 我认为它醒来很好,我使用的是WakefulIntentService,它使用的是PowerManager.WakeLock
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多