Alarm setExact()停止执行



目前我在安卓系统上的alarmManager有问题。

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

在这种模式下,AppReceiver应该精确地在每小时(第1分钟(调用一次。但它似乎只在几段时间内起作用。我昨天启动了警报,今天用adb shell dumpsys警报进行了检查。输出中没有提到警报?

我有以下情况:

  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()方法。

代码没有任何问题。问题出在我的华为智能手机的电源管理软件上。

正如我所发现的,几家公司(华为、三星、小米…(的一些安卓版本有更严格的电源管理规则。

如果应用程序被用户强制退出,警报将再工作几个小时。然后是设备上的电源管理软件,它会杀死所有未运行应用程序的后台服务。

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

解决我的情况:

  1. 停用我的应用程序的电源管理
  2. 再次启动警报

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

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

了解您的应用程序是否已停止。该值应为false。这意味着后台任务是一个正在运行的,它没有被电源管理软件杀死。

adb shell dumpsys package $packageName |grep stopped

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

adb shell dumpsys alarm |grep -C4 $packageName

最新更新