警报 setExact() 停止执行

Alarm setExact() stops executing

目前 Android 上的 alarmManager 有问题。

当我启动我的应用程序时,我调用方法 "startReminderAlarm"。现在在即将到来的小时和分钟 1 触发警报。警报触发 AppReceiver。 AppReceiver 在下一个小时和分钟 1 再次启动警报,然后在 "doInBackground" 方法中执行一些代码。

使用此模式,AppReceiver 应准确地在每小时(第 1 分钟)被调用。但它似乎只在几个时间间隔内有效。我昨天启动了警报,今天用 adb shell dumpsys alarm 检查了它。输出中未提及警报?

我有以下情况:

  1. 我无法在模拟器中重现这个问题
  2. 当我将闹钟更改为每分钟触发时,它似乎起作用了。

我的问题是:

  1. 我的代码有问题吗?
  2. 是否有日志文件,我可以在其中查看后台执行期间可能发生的异常?

我的代码:

// Class AlarmStarter
public static void startReminderAlarm(Context context){
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.HOUR, 1);
    calendar.set(Calendar.MINUTE, 1);
    calendar.set(Calendar.SECOND, 0);
    Log.i(TAG,"Start reminder alarm on " +sdf.format(new Date(calendar.getTimeInMillis())));

    AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent reminderIntent = new Intent(context, AppReceiver.class);
    PendingIntent reminderPendingIntent = PendingIntent.getBroadcast(context, 0, reminderIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    alarmMgr.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), reminderPendingIntent);
}

// Class AppReceiver
public class AppReceiver extends BroadcastReceiver {

    private static final String TAG = "AppReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        AlarmStarter.startReminderAlarm(context);
        new notifyAsyncTask().execute(context);
    }

    private static class notifyAsyncTask extends AsyncTask<Context, Void, Void> {

        private String CHANNEL_ID = "1a2b3c4d";

        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        @Override
        protected Void doInBackground(Context... params) {
            // DO SOME CODE
        }
    }
}

检查您的设备(或模拟器)版本以获取 setExec() 方法。 如果版本高于22,你应该使用setExactAndAllowWhileIdle()方法。

代码完全没有问题。问题出在我的华为手机的电源管理软件上。

据我所知,来自几家公司(华为、三星、小米...)的某些 Android 版本具有更严格的电源管理规则。

如果某个应用被用户强制退出,闹钟会再工作几个小时。然后是设备的电源管理软件,它会为非 运行ning 的应用程序终止所有后台服务。

这就是为什么它总是在模拟器中工作,而不是在我的智能手机上工作。

针对我的情况的解决方案:

  1. 为我的应用停用电源管理
  2. 再次启动闹钟

如果其他人遇到此问题,请检查您的电源管理设置!

在这种情况下一些有用的 adb 命令:

查明您的应用程序是否已停止。该值应为 false。这意味着后台任务 运行ning 并且没有被电源管理软件杀死。

adb shell dumpsys package $packageName |grep stopped

显示包裹的 运行ning 警报和一些附加信息,例如自上次 运行 以来经过了多少时间:

adb shell dumpsys alarm |grep -C4 $packageName