简体   繁体   English

小部件,AlarmManager和KitKat API19

[英]Widgets, AlarmManager and KitKat API19

Since API19 (KitKat), AlarmManager broadcasts are not acted on immediately, but batched together. 从API19(KitKat)开始,AlarmManager广播不会立即起作用,而是一起处理。
The documentation says that it should act immediately in KitKat if the app is targeted to API 18 or less, but this doesnt seem to work. 该文档说,如果该应用程序针对API 18或更低版本,则应立即在KitKat中采取措施,但这似乎不起作用。
Example, my clock widget is targeted to API 18 but it doesnt update when required on KitKat emulator (i dont have a device to test on). 例如,我的时钟小部件以API 18为目标,但在KitKat模拟器上要求时它不会更新(我没有要测试的设备)。 I read online that many people report their old clock widgets no longer updating on their KitKat devices. 我在网上阅读到很多人报告说他们的旧时钟小部件不再在其KitKat设备上更新。
The AlarmManager doc suggests this is to avoid wakeups, but it affects my RTC alarm also. AlarmManager文档建议这样做是为了避免唤醒,但它也会影响我的RTC警报。


The docs suggest setExact, but this is only for API19+. 文档建议使用setExact,但这仅适用于API19 +。 Is there a way to trigger updates that will be processed immediately on API8+ including API19? 有没有办法触发将在包括API19在内的API8 +上立即处理的更新? Or is it better to add a separate AlarmManager for API19+? 还是为API19 +添加单独的AlarmManager更好?
What could be a good solution for getting widgets to update properly on API19+ and still work properly on older devices? 什么是使小部件在API19 +上正确更新并在旧设备上仍能正常工作的好解决方案?

One strategy that has a single solution for both pre-API19 and API19+ that works for me: 一种适用于我之前的API19和API19 +单一解决方案的策略:
replace AlarmManager's setRepeating() broadcast with a new set() / setExact() created each time the widgets are updated. 每次更新小部件时,用创建的新set() / setExact()替换AlarmManager的setRepeating()广播。
This strategy allows continued use of AlarmManager's RTC alarm type, which doesnt trigger while the phone is asleep. 此策略允许继续使用AlarmManager的RTC警报类型,该类型在电话处于休眠状态时不会触发。
It causes the widget to update at the intended time on any API and keeps my widget as power efficient as it was using setRepeating() . 它会导致小部件在任何API上的预期时间进行更新,并使我的小部件保持与使用setRepeating()一样高效。

Instead of creating a setRepeating() alarm in the onEnabled method in the "widget manager" class... 而不是在“窗口小部件管理器”类的onEnabled方法中创建setRepeating()警报...
Create a set() for API18 or less, or setExact() for API19+ in the "Update Widget" class, after the widget update code is run. 运行窗口小部件更新代码后,在“ Update Widget”类中为API18或更低版本创建set()或为API19 +创建setExact() Everytime the widget is updated, a new alarm is set for whatever time is next required. 每次更新小部件时,无论接下来需要什么时间,都会设置一个新的警报。
Here is a section of code (incomplete) from within onStartCommand() in the "updateservice" class, that is called by both onEnabled() and the broadcast receiver class. 这是“ updateservice”类中onStartCommand()中的一段代码(不完整),由onEnabled()和广播接收器类调用。

 public int onStartCommand(Intent intent, int flags, int startId) { Log.w(LOG, "UpdateService.onStartCommand activated"); // reset the time dependent millis addition long alarmAddMillis = 0; // get time instance and values Calendar rightNow = Calendar.getInstance(); int thisMin = rightNow.get(Calendar.MINUTE); int thisHour = rightNow.get(Calendar.HOUR); // set correct hour values to update widget nextHour = thisHour + 1; if (thisHour == 0) {thisHour = 12;} if (nextHour == 13) {nextHour = 1;} // set text values based on minutes // set the values for the next alarm time if (thisMin >= 0 && thisMin <= 6) { clockH = thisHour; nextAlarmMin = 8; alarmAddMillis = 0;} if (thisMin >= 7 && thisMin <= 21) { clockH = thisHour; nextAlarmMin = 22; alarmAddMillis = 0;} if (thisMin >= 21 && thisMin <= 35) { clockH = thisHour; nextAlarmMin = 37; alarmAddMillis = 0;} if (thisMin >= 36 && thisMin <= 50) { clockH = nextHour; nextAlarmMin = 52; alarmAddMillis = 0;} if (thisMin >= 51 && thisMin <= 59) { clockH = nextHour; nextAlarmMin = 8; alarmAddMillis = 3600000;} 

----CODE FOR UPDATING THE WIDGETS GOES IN HERE---- ----更新小工具的代码在这里----

  // cancel any unsent alarm if (alarmManager != null){ alarmManager.cancel(pendingIntent); Log.w(LOG, "UpdateService.onStartCommand unsent alarm canceled");} // SET UP THE NEXT ALARM // set the time using values set above Calendar nextAlarm = Calendar.getInstance(); // add one hour of millis if its for the next hour nextAlarm.setTimeInMillis(System.currentTimeMillis() + alarmAddMillis); // set the correct minute nextAlarm.set(Calendar.MINUTE, nextAlarmMin); nextAlarm.set(Calendar.SECOND, 0); nextAlarm.set(Calendar.MILLISECOND, 0); // request the alarm alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); Intent usIntent = new Intent(this, AlarmReceiver.class); pendingIntent = PendingIntent.getBroadcast(this, 0, usIntent, 0); // ACCOUNT FOR DIFFERENT APIs HERE... // use onExact for API19+ int currentApiVersion = android.os.Build.VERSION.SDK_INT; if (currentApiVersion <= 18) { alarmManager.set(AlarmManager.RTC, nextAlarm.getTimeInMillis(), pendingIntent); Log.w(LOG, "FuzzyTimeWidget.onEnabled pre-kitkat AlarmManager requested"); }else{ alarmManager.setExact(AlarmManager.RTC, nextAlarm.getTimeInMillis(), pendingIntent); Log.w(LOG, "FuzzyTimeWidget.onEnabled API19+ AlarmManager requested"); } 


The only code required to manage the different API's is at the point of setting the alarm. 管理不同API所需的唯一代码是在设置警报时。 Just choosing set() or setExact() . 只需选择set()setExact() All the other code is for any API. 所有其他代码均适用于任何API。
In my case, I use nextAlarmMin to set the exact time for the next Alarm, which goes off 4 times per hour at 8, 22, 37, 52. 就我而言,我使用nextAlarmMin设置下一个警报的确切时间,该警报每小时会以nextAlarmMin的速度关闭4次。
For widgets that update every minute, I'm not sure how this strategy would be for the battery life. 对于每分钟更新的小部件,我不确定此策略在电池寿命方面的效果如何。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM