[Android] Doze mode で AlarmManager の繰り返しアラームを実装するには

AlarmManagerで繰り返しのアラーム機能を実装したいのですが、バックグラウンド実行制限があります。本来の機能として定期的なバックグラウンド処理のためにはちょっと工夫が必要です。
 
setexact 01b - [Android] Doze mode で AlarmManager の繰り返しアラームを実装するには

Android Studio 3.1.4
API 28

 



setExactAndAllowWhileIdle

 
Dozeモードはバッテリーの寿命を延ばすための省電力機能ですが、その制限事項として、標準AlarmMangerはメンテナンス時間枠まで保留になります。定期的なアラームは制限されるわけですが、

アラームのスケジュール設定をサポートするため、Android 6.0(API レベル 23)では、setAndAllowWhileIdle() と setExactAndAllowWhileIdle() という 2 つの新しい AlarmManager メソッドが導入されています。 このメソッドを使用すると、端末が Doze モードになっていてもアラームが発生するように設定できます。

Reference: Doze と App Standby 用に最適化する | Android Developers
ということで、このsetExactAndAllowWhileIdleを実装してみます。ただし、これも9分に1回までのようです。
 

 

繰り返し、Repeating

 
AlarmManagerにはsetRepeating()というのがありますが inexact つまりばらつきがある繰り返しになってしまいます。xxxAndAllowWhileIdleにsetRepeatingというのもありません。

ある程度精度があるアラームが必要な場合はsetExact… を使うことになりますが、Serviceで可能です。
Serviceが開始したところで次のサービスをAlarmManagerで呼び出すというやり方で実現できます。
TestService.java

 

startForegroundService()

 
ただ、Serviceはバックグラウンド制限のため今までのようには使えません。

Android 8.0 では、追加機能があります。システムは、バックグラウンド アプリによるバッグラウンド サービスの作成を許可しません。 そのため、Android 8.0 では、フォアグラウンドで新しいサービスを作成する Context.startForegroundService() メソッドが新たに導入されています。

Reference: バックグラウンド実行制限 | Android Developers
BackgroundではなくForegroundだと”言い張る”ということですか、はい。
このあたりはこちらで試しています。
 

service 00 100x100 - [Android] Doze mode で AlarmManager の繰り返しアラームを実装するには
Servce はバックグラウンドで作業をさせたい場合に使います。システムは直ぐにスリープに入れてしまいます。それでも裏で色々やりたい場合...

 
このForegroundServiceを使うためにはNotificationを使う必要があるため、通知エリアにはアイコンが表示され通知ドロワーにはアプリ名、そして通知音が鳴る(対策無しだと)ということになります。

 

サンプルコード

 
Doze中でも繰り返しができるように、15分に1回、作業は短く内部ストレージのファイルに時間を書き込むという形で作って見ました。
 
MainActivity.java

 
Serviceを実行するクラスを新しく作成します。
TestService.java

 
Manifest.xml

 
ファイル書込み読出し用のクラスです。
InternalFileReadWrite.java

 
レイアウトです。

 
strings.xml

 

結果

 
setExactAndAllowWhileIdle:15分間隔
これで一晩寝かせてみました。上のコードの通り15分間隔で時間を記録するアプリをstartさせて、アプリを終了。マルチタスクメニューからも削除。
 
alarm doze 01 - [Android] Doze mode で AlarmManager の繰り返しアラームを実装するには
 
夜7時頃から12時間です、ほぼ15分間隔で実行されていました、途中で多少ずれているのは不明です。完璧ではないということでしょうか。
 
setExactAndAllowWhileIdle:1分間隔
ついでに1分間隔でのテストもやってみました。
15分間隔のアラームを1分間隔に変更

 
alarm doze 02 - [Android] Doze mode で AlarmManager の繰り返しアラームを実装するには
 
最初は1分間隔ですがあるところで9分にさせられています。またあるところで1分間隔になったりしていますがこれは端末を持って移動していた時間帯です。深いDozeから浅いDoze、あるいはStand byになったのでしょうか。
 
setExact:1分間隔
正確なアラーム間隔ですが、Doze 中にどうなるかです
 

 
setExact 01 - [Android] Doze mode で AlarmManager の繰り返しアラームを実装するには
 
最初の1時間は1分間隔ですが、その後間隔が伸びて約2時間、4時間、6時間間隔となっていました。Dozeの影響でしょうか
 
関連ページ:

 
References:
サービス | Android Developers
バックグラウンド実行制限 | Android Developers
Service | Android Developers

誤字脱字、意味不明で分からにゃイ、
などのご意見はこちらから mailフォーム

ブックマークしておくと便利です このエントリーをはてなブックマークに追加




アプリ開発が上達するお勧め

アプリ開発を始めたけどわからないところがあり、誰かに聞きたいけど周りにはそんな人はいない…あるいは、会社で働いていて日中そんなに時間をとれないなど、オンラインのプログラミングスクールがいいでしょう、時間の制約がないところが一番の魅力です。

以下の3つはAndroidが学習できるオンラインスクールです。


TECH ACADEMY
Androidアプリコース



侍エンジニア塾
侍エンジニア塾 無料体験レッスン



CodeCamp
~約8,000名の受講生と80社以上の導入実績~
現役エンジニアのオンライン家庭教師CodeCamp





正直ネットや本では限界があります。直接(ネットで)誰か分かる人に聞いた方が早く解決して、上達も早いと思います。

尚、スクールがダメだと言う人がいますが、やる気があれば問題ありません。与えられるのを待っていてはいけないですね
欲しいものは取りに行くのです。


Google Pixel 3 XLグローバル版
SIMフリー 並行輸入品
6.3インチの大画面
背景をぼかすポートレートモード撮影


Anker PowerCore II Slim 10000
Power IQ 2.0搭載
iPhone & Android対応

シェアする

  • このエントリーをはてなブックマークに追加

フォローする