我已经在Google Play中创建并部署了一个闹钟应用。和往常一样,我在8个不同的真实设备(我不使用模拟器)中执行了大量的测试,运行不同的api级别,有根/无根,不同的时区,以及其他功能。
问题是,在达到超过10,000次下载后,一些用户抱怨在指定时间前1小时发出警报,而另一些用户(4倍数量)则抱怨警报在1小时后发生。我从世界不同的地方得到这个,我也从同一个地方得到5颗星。 我立刻想到我在我的代码的某些地方错误地使用了时区,但事实是我只是在使用
GregorianCalendar gc = new GregorianCalendar();
那种实例化是我通过我所有代码使用的实例。我使用系统AlarmManager设置闹钟,如:
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context.getApplicationContext(), AlarmReceiver.class);
GregorianCalendar gc = new GregorianCalendar();
long triggerAtMillis = 0;
if(nextAlarm != null){
triggerAtMillis = System.currentTimeMillis()
+ 60*1000*alarmDifference(nextAlarm, gc.get(Calendar.HOUR_OF_DAY), gc.get(Calendar.MINUTE), true)
- 1000*gc.get(Calendar.SECOND);
}else{
// Log.d("", "nextAlarm: NULL");
return;
}
PendingIntent operation = PendingIntent.getBroadcast(context.getApplicationContext(), REQUEST_CODE_ALARM_BROADCAST, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, operation);
alarmDifference方法非常简单:
public static int alarmDifference(Alarm alarm, int hour, int minute, boolean inverse) {
int hours = hour - alarm.getHour();
if(inverse){
hours *= -1;
}
if(hours < 0)
hours += 24;
int minutes = minute - alarm.getMinute();
if(inverse){
minutes *= -1;
}
if(hours==0 && minutes<0){
hours = 23; //this happens if we set the time to the current hour
}
if(minutes < 0)
minutes += 60;
// Log.d("", "Time left: "+ hours+" hours, " + minutes+" minutes");
return hours*60 + minutes;
}
我的目标是api级别17,因此我不会遇到系统不遵守交付时间的问题,并且必须使用 AlarmManager.setExact(...)。
要唤醒我的服务我正在使用WakefulBroadcastReceiver,所以我不必自己处理WakeLock。
我在网站上做了大量的研究,尝试过不同的方法而没有任何运气。
提前致谢。
答案 0 :(得分:1)
您可以尝试使用next来查找问题:
在您的应用中加载来自互联网服务的世界时间(例如,http://developer.yahooapis.com/TimeService/V1/getTime?appid=YahooDemo),并与设备上的时区进行比较。您可以在全局或应用中的设备中确定问题所在。
答案 1 :(得分:0)
我很确定问题出在这一行:
triggerAtMillis = System.currentTimeMillis()
+ 60*1000*alarmDifference(nextAlarm, gc.get(Calendar.HOUR_OF_DAY), gc.get(Calendar.MINUTE), true)
- 1000*gc.get(Calendar.SECOND);
此操作不保证以原子方式发生。换句话说,
可以在不同的时间发生,例如当时钟从14:59:99变换到15:00:00,所以你可能会得到14小时和00分钟,或15小时和59分钟
相反,我会从不可变的时间戳值中提取小时/分钟/秒。