目前,我正在尝试在特定时间运行一段代码。经过一些研究,我认为正确的方法是使用AlarmManger
。代码应该每天凌晨3点执行。如果手机在凌晨3点关闭,则应在打开手机后直接执行代码。
我用谷歌搜索了很多结果。但是我的代码没有正常工作。
昨天我收到了通知。通知时间是晚上10点。但在代码中,时间设置为凌晨3点。我随着时间的推移设置了很多报警管理器(因为测试)。是否有可能触发的AlarmManager是旧的?注意:在设置新的AlarmManager之前,我从手机中删除了完整的应用程序并将其安装为新的。 (我想这会删除所有设置的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();
方法内)。
答案 0 :(得分:4)
注意:从API 19开始,所有重复警报都不准确。如果您的应用程序需要精确的交付时间,则必须使用一次性精确警报,每次重新安排。
不精确的调度意味着任何两次连续发射警报之间的时间可能会有所不同。多数民众赞成在你的情况下发生的事情我想。为了克服确切的时间问题,我认为你应该使用一次性警报。但在这种情况下,你需要重新安排它第二天。等等。 您可以从文档setrepeating,setInexactRepeating中获得非常清晰的理解。
编辑: - 优化DOZE模式
如果您使用runas
或setAndAllowWhileIdle()
,
然后,您必须阅读This Document,其中包含: -
setAndAllowWhileIdle()和setExactAndAllowWhileIdle()都不能每个应用每9分钟触发一次警报。
答案 1 :(得分:0)
我认为这是因为Power Manager会导致App Actvivity出现问题。
尝试使用Power Manager
PARTIAL_WAKE_LOCK
在API级别1中添加 int PARTIAL_WAKE_LOCK 唤醒锁定级别:确保CPU正在运行;屏幕和键盘背光将被允许熄灭。
如果用户按下电源按钮,屏幕将关闭,但CPU将保持打开状态,直到所有部分唤醒锁定都被释放。
常数值:1(0x00000001)
这只是一个假设,如果它仍然不起作用,你可以发布一些日志或更多活动的代码片段:)
示例:
//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();
}