Android 19 からAlarmMangerでの、set()、setRepeating()などの時間経過の誤差が大きくなりました。(inexact になったとあります)
理由は、バッテリー電力消費量を改善するためのようですが、実際どの程度なのか試してみました。
setRepeating(), set()のinexact
確かに、毎朝7時のアラームが7時1分であれば、多少は許容される場合もあるでしょうが
そもそも誤差がどれだけなのかよくわかりません。OSに依存させているというのは、けっこう出たとこ勝負ではないでょうか。
テストを実施してみました。
Activity から Service を呼び、AlarmManager にそれぞれのメソッドをセットします
アラーム起動は1秒後で、その後1分間隔で繰り返すテストです
Nexus7 2013 を使用
またスマホはwakeupの状態
targetSdkVersion = 25 です
setRepeating
1 2 3 4 5 6 7 8 9 10 |
03-14 11:28:38.185 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:29:38.206 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:30:38.198 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:31:43.034 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:33:01.045 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:33:53.729 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:34:53.735 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:35:53.735 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:37:14.438 8451-8451/com.example.testalarm D/Service﹕ received 03-14 11:37:38.209 8451-8451/com.example.testalarm D/Service﹕ received |
相当ばらついています
1分間隔ですが24秒後にアラームが出てることもあります
set
setは単発アラームなので、Serviceでアラーム起動後、次のアラームを設定する方法をとりました
1 2 3 4 5 6 7 8 9 10 |
03-13 22:38:31.658 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:39:36.340 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:40:36.377 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:41:55.403 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:42:56.364 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:43:56.410 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:45:01.056 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:46:01.094 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:47:01.125 11912-11912/com.example.testalarm D/Service﹕ received 03-13 22:48:01.993 11912-11912/com.example.testalarm D/Service﹕ received |
毎回設定しているためか、setRepeating よりはマシですが
時々ズレます
setExact
1 2 3 4 5 6 7 8 9 10 |
03-14 12:27:08.585 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:28:08.606 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:29:08.626 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:30:08.636 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:31:08.641 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:32:08.659 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:33:08.686 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:34:08.706 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:35:08.726 11711-11711/com.example.testalarm D/Service﹕ received 03-14 12:36:08.760 11711-11711/com.example.testalarm D/Service﹕ received |
setExact のReferenceでは
http://developer.android.com/reference/android/app/AlarmManager.html#setExact(int, long, android.app.PendingIntent)
This method is like set(int, long, PendingIntent), but does not permit the OS to adjust the delivery time. The alarm will be delivered as nearly as possible to the requested trigger time. |
ということで、努力目標でしょうか
CPUに負荷がかかってしまうと確実ではないような感じですね
setWindow
window の幅は 1000 msec に設定
1 2 3 4 5 6 7 8 9 10 |
03-14 12:51:45.646 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:52:45.654 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:53:45.661 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:54:45.677 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:55:45.694 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:56:45.705 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:57:46.546 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:58:46.567 13586-13586/com.example.testalarm D/Service﹕ received 03-14 12:59:46.585 13586-13586/com.example.testalarm D/Service﹕ received 03-14 13:00:47.425 13586-13586/com.example.testalarm D/Service﹕ received |
SetWindow のReferenceでは
http://developer.android.com/reference/android/app/AlarmManager.html#setWindow(int, long, long, android.app.PendingIntent)
Schedule an alarm to be delivered within a given window of time. This method is similar to set(int, long, PendingIntent), but allows the application to precisely control the degree to which its delivery might be adjusted by the OS. |
windowの範囲内であればOSが調整してくれる(たぶん)
ということですね
window の範囲内でアラームが出ていますが
繰り返しによる遅れがだんだん積み重なっています
setWindow、setExact 以外に繰り返しのAPIがないようです
x setExactRepeatingというのが無い
setWindowがとりあえず、バッテリー消費と時間精度の妥協策でしょうか