运行 每天在特定时间编码 - AlarmManager

Run code every day at a specific time - AlarmManager

目前,我正尝试在特定时间运行一段代码。经过一些研究,我认为正确的方法是使用 AlarmManger。代码应在每天凌晨 3 点执行。如果phone在凌晨3点关机,那么代码应该在phone打开后直接执行。

我用谷歌搜索并找到了很多结果。但是我的代码无法正常工作。

昨天我收到通知。通知时间是晚上10点。但在代码中,时间设置为凌晨 3 点。这段时间我设置了很多警报管理器(因为测试)。有没有可能触发的 AlarmManager 是旧的?注意:在设置新的 AlarmManager 之前,我从 phone 中删除了完整的应用程序并重新安装了它。 (我认为这会删除所有设置的 AlarmManager?)

好的,这是我使用的代码:

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 0);
calendar.add(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR, 3);

Intent _myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
_myIntent.putExtra("MyMessage","Content of the message");
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 123, _myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager alarmManager = (AlarmManager) MainActivity.this.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*60*60*24, pendingIntent);

这段代码将在我的应用程序每次启动时执行(在 MainActivity's onCreate(); 方法中)。

我认为这是因为电源管理器导致 App Actvivity 出现问题。

尝试使用 Power Manager

PARTIAL_WAKE_LOCK

added in API level 1 int PARTIAL_WAKE_LOCK Wake lock level: Ensures that the CPU is running; the screen and keyboard backlight will be allowed to go off.

If the user presses the power button, then the screen will be turned off but the CPU will be kept on until all partial wake locks have been released.

Constant Value: 1 (0x00000001)

这只是一个假设,如果它仍然不起作用,你能不能post一些日志或activity的更多代码片段:)

示例:

//Initialize the Power Manager
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

 //Create a PARTIAL_WAKE_LOCK
 //This will keep the cpu running in the Background, so that the function will be called on the desired Time
 PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");

//Check if the WackLock is held (may throw erro if you try to acquire twice)
//TRUE --> Do nothing, all good
//FALSE --> Acquire the WakeLock
 if(!wl.isHeld()){
    wl.acquire();
 }

//*****
//You code for the repeating task goes Here
//*****

//If the Repeating task is not active, release the Lock

//Check if the WackLock is held (may throw error if you try to release a none acquired Lock)
//TRUE --> Release Lock
//FALSE --> Do nothing, all good
 if(wl.isHeld()){
    wl.release();
 }

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time.

不精确的时间安排意味着任何两次连续触发警报之间的时间可能会有所不同。这就是你的情况,我 guess.To 克服了确切的时间问题,我认为你应该使用一次拍摄 alarm.But 在这种情况下你需要重新安排第二天。等等。 你可以从文档setrepeating , setInexactRepeating.

中得到非常清晰的理解

编辑:- 优化 DOZE 模式 如果您使用 setAndAllowWhileIdle()setExactAndAllowWhileIdle(), 然后你必须阅读 This Document 上面写着:-

Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 9 minutes, per app.