警报setExact()停止执行

时间:2018-11-20 10:25:58

标签: java android alarmmanager

当前,我在Android上使用alarmManager遇到问题。

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

使用这种模式,应该在每小时(第1分钟)准确调用一次AppReceiver。但是它似乎仅在几个时间间隔内起作用。我昨天启动了警报,今天用 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
        }
    }
}

2 个答案:

答案 0 :(得分:1)

检查您的设备(或仿真器)的版本是否为setExec()方法。 如果版本高于22,则应使用setExactAndAllowWhileIdle()方法。

答案 1 :(得分:0)

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

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

如果用户强制退出某个应用,则闹钟将继续工作几个小时。然后,设备会附带电源管理软件,并杀死所有未运行的应用程序的后台服务。

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

我的情况的解决方案:

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

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

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

了解您的应用是否已停止。该值应为false。这意味着后台任务正在运行,并且未被电源管理软件终止。

adb shell dumpsys package $packageName |grep stopped

显示软件包的运行警报以及一些其他信息,例如自上次运行以来经过了多少时间:

adb shell dumpsys alarm |grep -C4 $packageName