mit*_*nia 7 java android alarmmanager
我正在开发一个应该每60秒执行一次任务的应用程序.由于Android 4.4+中的警报存在一些准确性问题,其中所有警报都不准确,我选择了链式模型:A BroadcastReceiver触发第一个警报,每个警报依次设置下一个警报.
问题是,即使我以60秒(60000毫秒)的间隔设置警报,警报也会以5秒的间隔触发,有时甚至更少.我已经在我的Nexus 5(Android 5.1.1)和Android 5.0.1仿真器上测试了代码,两者都给出了相同的结果.我应该指出,两个接收器都在AndroidManifest上注册,我的应用程序具有RECEIVE_BOOT_COMPLETED权限.
编辑:setExact()导致完全相同的问题
StartupReceiver.java(BroadcastReceiver for BOOT_COMPLETED):
public class StartupReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Got the BOOT_COMPLETED signal");
// Get the first alarm to be invoked immediately
AlarmReceiver.setNextScanAlarm(context, 0);
}
}
Run Code Online (Sandbox Code Playgroud)
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Start the service
Intent startServiceIntent = new Intent(context, BackgroundService.class);
startServiceIntent.putExtra("interval", 60000);
startServiceIntent.putExtra("action", "scan");
context.startService(startServiceIntent);
// Schedule the next alarm
setNextScanAlarm(context, 60000);
}
public static void setNextScanAlarm(Context context, int interval) {
Intent scanIntent = new Intent(context, AlarmReceiver.class);
scanIntent.putExtra("interval", interval);
scanIntent.putExtra("action", "scan");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
scanIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
pendingIntent);
}
}
Run Code Online (Sandbox Code Playgroud)
可能是什么问题呢?
我相信,因为这是打电话时的闹钟
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
pendingIntent);
Run Code Online (Sandbox Code Playgroud)
您调用的变量interval是您想要在下一个警报之前经过的时间,但是当您考虑这个时,它知道什么时候开始?更重要的是,时间什么时候实际上为零?
当你创建它时?不,
你什么时候打电话.set()?不。
它实际上在启动时为零。所以你要求它在启动后 60 秒启动,并且你每次都要求这个,这个时间已经过去了。
这就是令人困惑的地方,您可能应该只使用类似的调用new
Handler.postDelayed(Runnnable r, 60000)而不是警报管理器。它会更加准确,并且不会在理解 Android 操作系统及其闹钟/时钟/等方面遇到一些问题。
但对于您的具体情况,我相信您可以通过访问System函数调用/变量来解决它。所以在你的函数内部setNextScanAlarm()我相信它会是这样的:
public static void setNextScanAlarm(Context context, int interval) {
//create the intent the same way as before
Intent scanIntent = new Intent(context, AlarmReceiver.class);
scanIntent.putExtra("interval", interval);
scanIntent.putExtra("action", "scan");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
scanIntent,
PendingIntent.FLAG_ONE_SHOT);
//create new variables to calculate the correct time for this to go off
long timeRightNow = System.elapsedRealTime() //use something else if you change AlarmManager type
long timeWhenIShouldGoOff = timeRightNow + interval;
//use the new timeWhenIShouldGoOff variable instead of interval
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
timeWhenIShouldGoOff,
pendingIntent);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1164 次 |
| 最近记录: |