Dozeモードの存在(Android 6.0以降)
Android OSにおける「Doze」は、デバイスのバッテリー消費を抑えるための省電力機能です。デバイスが一定期間使用されず、かつ画面がオフの状態で動きがないときに、自動的にDozeモードに入ります。このモードでは、バックグラウンドでのネットワークアクセスやシステム同期が制限され、CPUを含むシステムの動作を最低限に抑えます。ただし、重要な通知や優先されるアプリは例外として処理されるよう設計されています。
DozeはAndroid 6.0(Marshmallow)から導入され、その後のバージョンでさらに改良されています。
バックグラウンドアプリへの影響
Doze機能による制約がバックグラウンドでのアプリ通信に影響します。Android 8.1 から、アプリがバックグラウンドで実行されている間は、ネットワークアクセス(特にWi-Fiやモバイルデータ通信)が制限されるため、リアルタイムな通信やバックグラウンド同期を行うアプリの動作に影響が出ることがあります。
Dozeの具体的な制約
1. バックグラウンドのネットワークアクセス制限
Dozeモードに入ると、バックグラウンドでのネットワークアクセスは制限され、定期的にしか許可されません。これにより、バックグラウンドでのデータの送受信が遅れる場合があります。
2. 一定時間の待機後にモード移行 デバイスが一定時間動作しない(画面オフ状態が続く)場合、Dozeモードに移行し、CPUのスリープ、ネットワークアクセスの制限、ジョブやアラームの遅延などが発生します。
3. アプリごとの制約レベルの強化 Android 8.1では、バックグラウンドでアクティブなアプリやサービスがさらに厳密に管理されており、通常のDozeよりも頻繁に制約される「バックグラウンド制約モード」に入ることがあります。
通信制約を回避する方法
アプリがリアルタイムの通知や通信を必要とする場合は、以下の設定や実装を検討します:
1. Firebase Cloud Messaging(FCM)を使用したプッシュ通知
FCMを利用することで、Dozeモードでも優先的に通知を受信し、アプリを起動することができます。 2. Foreground Service(フォアグラウンドサービス)の利用 バックグラウンド制約を回避するために、フォアグラウンドサービスを使ってユーザーに「アプリが動作中であること」を通知し、通信を継続する方法があります。 3. Dozeの例外設定(ホワイトリスト) システム設定から特定のアプリをバッテリー最適化の対象外に設定すると、Dozeモード中でも通信が許可されることがあります(ただし、ユーザーの手動設定が必要です)。
このように、Doze機能による制約を考慮しながら、アプリが正しくバックグラウンド通信を行えるように設計することが重要です。
バックグラウンドでのポーリング処理における制約
AndroidのDozeモードとバックグラウンド制約では、アプリがバックグラウンドで行えるポーリングの頻度がかなり制限されます。具体的には以下のような制約があります。
Dozeモードの制約
1. Dozeモード中 通信は「メンテナンスウィンドウ」と呼ばれる短時間の間隔でしか許可されません。通常、10分~1時間に1回程度です。
2. バックグラウンド制約(App Standby) Android 8.1以降では、アプリのバックグラウンド動作がさらに厳しく管理され、非アクティブアプリの場合は数時間単位でしかジョブが実行されない場合もあります。
効果的な対応策
ポーリングの代わりに、**Firebase Cloud Messaging(FCM)**のようなリアルタイム通知を利用するか、WorkManagerを使用して定期的なジョブを設定することが推奨されます。これにより、バッテリー消費を抑えつつ、必要なタイミングでサーバーと通信できます。
WorkManagerを使用した場合の制限事項
WorkManager は毎分(1分間隔)での実行には適していません。WorkManager は、長時間のバックグラウンド処理やバッテリー消費を考慮したタスク実行のために設計されており、頻度の高いジョブ(毎分など)を設定することは推奨されていません。また、Androidのバッテリー管理機能(DozeやApp Standby)によって、最短でも15分程度の間隔が推奨されています。
もし毎分ごとにポーリングしたい場合は、**Foreground Service(フォアグラウンドサービス)**の使用や、Androidバッテリー管理設定の対象外にする方法を検討する必要があります。
代替案
1. Foreground Service
フォアグラウンドでアクティブな状態で動作し続けることができるため、毎分ポーリングが必要な場合はこちらを検討。
2. JobScheduler / AlarmManager WorkManager よりも短時間の間隔でタスクをスケジューリングできる場合がありますが、バッテリー消費やDozeモードの影響を受けやすいです。
3. Firebase Cloud Messaging(FCM) リアルタイム通知や、サーバーのイベントに応じて通信をトリガーしたい場合には、FCMを活用することをおすすめします。
WorkManagerは、15分以上の定期ジョブに適しているため、毎分通信を必要とする場合は上記の方法を検討するのが良いでしょう。
バッテリーが搭載されていない商用電源だけで動作するAndroid端末での制約
バッテリーのない、常に電源供給されているAndroidデバイスでも、Dozeモードやバックグラウンド制約は適用されます。これは、Android OSのバッテリー最適化が「電力供給」に基づいているのではなく、バッテリー消費を管理し、システムのパフォーマンスを最適化することを目的としているためです。
ただし、電源が常に供給されているデバイスでは、次のような方法で制約を緩和できる場合があります。
- Battery Optimization(バッテリー最適化)の無効化
- 設定メニューで特定のアプリをバッテリー最適化の対象外に設定することができます。この設定により、Dozeモード中でもアプリのバックグラウンド活動が許可される可能性があります。
- 手動設定手順:設定 > バッテリー > バッテリー最適化 からアプリを選択し、「最適化しない」を選ぶ。
- デバイス管理者設定(Device Owner)の活用
- 企業や特定のビジネス用途のデバイスの場合、管理者権限を持っていれば、アプリの制約を緩和する設定を行うことが可能です。
- 特定の開発オプションを有効化する
- 開発者向けオプションにある「Dozeを無効にする」設定をオンにすることで、アプリの動作がDozeの影響を受けにくくなります(ただし、これを設定しても完全に制約を無視することはできません)。
- アプリの設計見直し
- 毎分のポーリングが必要なケースは、アプリをフォアグラウンドで動作させ、ユーザーに通知を表示するなどの設計を検討してください(これによりバックグラウンド制約を回避できます)。
つまり、常に電源が供給されているデバイスでもAndroidのバッテリー管理制約はデフォルトでは有効なので、上記の設定や手法を活用して緩和することをお勧めします。