Doze とアプリ スタンバイ用に最適化する

Android には、デバイスが電源に接続されていないときのアプリの動作を管理することで、バッテリー駆動時間を延ばす 2 つの省電力機能(Doze とアプリ スタンバイ)があります。Doze は、デバイスが長時間にわたって使用されない場合、アプリのバックグラウンド CPU とネットワーク アクティビティを保留にして電池消費量を削減します。アプリ スタンバイは、最近ユーザー アクティビティがないアプリのバックグラウンド ネットワーク アクティビティを延期します。

デバイスが Doze モードの間、アプリによるバッテリー消費量の多い特定のリソースへのアクセスは、メンテナンスの時間枠まで延期されます。個別の制限事項は電源管理に関する制限に記載されています。

Doze とアプリ スタンバイは、Android 6.0 以降で動作するすべてのアプリの動作を管理します。アプリが対象 API レベル 23 をターゲットにしているかどうかは関係ありません。ユーザーに最適なエクスペリエンスを提供するには、Doze モードとアプリ スタンバイ モードでアプリをテストし、必要に応じてコードを調整します。以下で詳細について説明します。

Doze を理解する

ユーザーがデバイスを電源に接続せず、画面をオフにした状態で一定時間放置すると、デバイスは Doze モードに入ります。Doze モードでは、アプリによるネットワークや CPU を集中的に使用するサービスへのアクセスを制限することで、バッテリーを節約しようとします。また、アプリがネットワークにアクセスできないようにし、ジョブ、同期、標準アラームを遅らせます。

システムは定期的に Doze モードを短時間終了し、アプリが保留中のアクティビティを完了できるようにします。このメンテナンスの時間枠の間、システムは保留中のすべての同期、ジョブ、アラームを実行し、アプリがネットワークにアクセスできるようにします。

図 1. Doze は、アプリがネットワークを使用し、保留中のアクティビティを処理するためのメンテナンスの時間枠を定期的に提供します。

メンテナンスの時間枠が終了すると、システムは再び Doze モードに入り、ネットワーク アクセスを一時停止し、ジョブ、同期、アラームを延期します。時間の経過とともに、システムはメンテナンスの時間枠のスケジュール設定の頻度を減らします。これにより、デバイスが充電されていない状態で長時間使用されていない場合のバッテリー消費を抑えることができます。

ユーザーがデバイスを動かしたり、画面をオンにしたり、充電器に接続したりしてデバイスを復帰させると、システムは Doze を終了し、すべてのアプリが通常のアクティビティを再開します。

Doze の制限事項

システムは、アプリが Doze モードの間、次の制限を適用します。

  • ネットワーク アクセスを一時停止します。
  • wake lock を無視します。
  • setExact() や setWindow() などの標準の AlarmManager アラームを次のメンテナンスの時間枠まで延期します。
    • Doze 中に起動するアラームを設定する必要がある場合は、setAndAllowWhileIdle() または setExactAndAllowWhileIdle() を使用します。
    • setAlarmClock() で設定されたアラームは、通常どおり起動します。システムは、これらのアラームがトリガーされる直前に、Doze を終了します。
  • Wi-Fi スキャンを行わない。
  • 同期アダプターの実行を許可しません。
  • JobScheduler の実行を許可しません。

Doze チェックリスト

  • 可能な場合、ダウンストリーム メッセージングには Firebase Cloud Messaging(FCM)を使用します。
  • ユーザーがすぐに通知を表示する必要がある場合は、RemoteNotification メッセージ タイプを使用してください。詳しくは、RemoteNotification メッセージ タイプに関する FCM のドキュメント をご覧ください。
  • 最初のメッセージ ペイロード内に十分な情報を含めます。これにより、その後のネットワーク アクセスが不要になります。
  • setAndAllowWhileIdle() と setExactAndAllowWhileIdle() で重要なアラームを設定します。
  • Doze でアプリをテストする。

Doze 向けにアプリを調整する

Doze がアプリに与える影響は、アプリが提供する機能や使用するサービスによって異なります。多くのアプリは、変更を加えなくても Doze サイクル全体で正常に機能します。場合によっては、アプリがネットワーク、アラーム、ジョブ、同期を管理する方法を最適化する必要があります。アプリは、各メンテナンスの時間枠中にアクティビティを効率的に管理できる必要があります。

アラームのスケジュール設定に役立つ AlarmManager メソッドとして、setAndAllowWhileIdle() と setExactAndAllowWhileIdle() の 2 つを使用できます。これらのメソッドを使用すると、デバイスが Doze モードであっても起動するアラームを設定できます。

ネットワーク アクセスに対する Doze の制限も、アプリに影響する可能性があります。特に、アプリがティックルや通知などのリアルタイム メッセージに依存している場合は、その可能性が高くなります。メッセージを受信するためにアプリがネットワークへの永続的な接続を必要とする場合は、可能であれば Firebase Cloud Messaging(FCM)を使用します。

アプリが Doze で想定どおりに動作することを確認するには、adb コマンドを使用してシステムを強制的に Doze に移行させたり、Doze から復帰させたりして、アプリの動作を観察します。詳しくは、Doze モードとアプリ スタンバイ モードでテストするをご覧ください。

アプリ スタンバイについて

アプリ スタンバイでは、ユーザーがアプリをアクティブに使用していないときに、システムがアプリをアイドル状態と判断します。システムは、ユーザーが一定期間アプリを操作せず、次の条件のいずれも適用されない場合に、この判断を行います。

  • ユーザーがアプリを明示的に起動している。
  • アプリに、アクティビティまたはフォアグラウンド サービスとして、または別のアクティビティまたはフォアグラウンド サービスで使用中の、フォアグラウンドに現在存在するプロセスがある。
  • アプリが通知を生成し、ユーザーがロック画面または通知トレイで通知を確認する。

ユーザーがデバイスを電源に接続すると、システムはアプリをスタンバイ状態から解放し、ネットワークに自由にアクセスして、保留中のジョブや同期を実行できるようにします。デバイスが長時間アイドル状態の場合、システムはアイドル状態のアプリに 1 日に 1 回程度ネットワーク アクセスを許可します。

デバイスがアイドル状態のときに FCM を使用してアプリを操作する

Firebase Cloud Messaging(FCM)は、バックエンド サービスと Android デバイス上のアプリの間でリアルタイムのダウンストリーム メッセージングをサポートできるクラウドツードバイス サービスです。FCM は、クラウドへの単一の永続的な接続を提供します。リアルタイム メッセージングを必要とするすべてのアプリがこの接続を共有できます。この共有接続により、複数のアプリがそれぞれ独自の永続的な接続を維持する必要がなくなるため、バッテリーの消費が大幅に最適化されます。このため、アプリでバックエンド サービスとのメッセージング統合が必要な場合は、独自の永続的なネットワーク接続を維持するのではなく、可能であれば FCM を使用することを強くおすすめします。

FCM は、Doze モードとアプリ スタンバイ アイドル モードで動作するように最適化されています。FCM の RemoteNotification メッセージ タイプを使用すると、アプリを起動してユーザーに働きかけることができます。Doze モードまたはアプリ スタンバイ モードでは、システムはメッセージを配信し、アプリにネットワーク サービスと部分的な wake lock への一時的なアクセスを許可してから、デバイスまたはアプリをアイドル状態に戻します。時間的制約のある、ユーザーに表示される通知については、RemoteNotification メッセージ タイプを使用して、Doze モードでの配信を有効にすることを検討してください。これらのメッセージは通知につながる可能性があります。詳しくは、RemoteNotification に関する FCM のガイダンスをご覧ください。

バックグラウンドでのアプリ コンテンツの更新やデータ同期の開始など、通知を伴わないメッセージには、BackgroundSync FCM メッセージを使用します。これらのメッセージは意図的に優先度が低く設定されており、デバイスのバッテリーを最適化するために遅延またはスロットルされることがあります。

一般的なベスト プラクティスとして、アプリでダウンストリーム メッセージングが必要な場合は、FCM を使用します。アプリですでに FCM を使用している場合は、ユーザー向けの通知を生成するメッセージに RemoteNotification が使用されていることを確認します。

次のような状況では RemoteNotification を使用しないでください。

  • 通知が確実に表示されない場合。
  • アプリの状態を更新するだけのメッセージ(バックグラウンドでアプリのコンテンツを最新の状態に保つ、データ同期を開始するなど)を即時に配信する場合。
  • エンドユーザーに権限の付与を求める手段として。

その他のユースケースのサポート

ほぼすべてのアプリは、ネットワーク接続、アラーム、ジョブ、同期を管理し、FCM メッセージを使用することで、Doze をサポートできます。一部のユースケースでは、これでは不十分な場合があります。このような場合のために、システムには、Doze とアプリ スタンバイの最適化から部分的に除外されるアプリの構成可能なリストが用意されています。

部分的に除外されたアプリは、Doze モードとアプリ スタンバイ モードの間、ネットワークを使用し、部分的な wake lock を保持できます。ただし、他のアプリと同様に、アプリには他の制限が適用されます。たとえば、API レベル 23 以前では、アプリのジョブと同期が延期され、通常の AlarmManager アラームは起動しません。アプリは、isIgnoringBatteryOptimizations() を呼び出すことで、現在除外リストに登録されているかどうかを確認できます。

ユーザーは、[設定] > [バッテリー] > [バッテリーの最適化] で、除外するアプリのリストを手動で設定できます。また、アプリがユーザーに除外をリクエストする方法も用意されています。

アプリは、isIgnoringBatteryOptimizations() を呼び出すことで、現在除外リストに登録されているかどうかを確認できます。

Doze モードとアプリ スタンバイ モードでテストする

ユーザーに優れたエクスペリエンスを提供できるように、Doze モードとアプリ スタンバイ モードでアプリを十分にテストしてください。

Doze でアプリをテストする

Doze モードをテストする手順は次のとおりです。

  1. Android 6.0(API レベル 23)以上のシステム イメージを使用して、ハードウェア デバイスまたは仮想デバイスを構成します。
  2. デバイスを開発用 PC に接続してアプリをインストールします。
  3. アプリを実行してアクティブ状態のままにします。
  4. 次のコマンドを実行して、システムを強制的にアイドルモードにします。
        $ adb shell dumpsys deviceidle force-idle
        
  5. 準備ができたら、次のコマンドを実行してアイドルモードを終了します。
        $ adb shell dumpsys deviceidle unforce
        
  6. 次のコマンドを実行してデバイスを再有効化します。
        $ adb shell dumpsys battery reset
        
  7. デバイスを再びアクティブ状態にした後のアプリの動作を監視します。デバイスが Doze モードを終了したときに、アプリが正常に復帰することを確認します。

アプリ スタンバイでアプリをテストする

アプリでアプリ スタンバイ モードをテストする手順は次のとおりです。

  1. Android 6.0(API レベル 23)以上のシステム イメージを使用して、ハードウェア デバイスまたは仮想デバイスを構成します。
  2. デバイスを開発用 PC に接続してアプリをインストールします。
  3. アプリを実行してアクティブ状態のままにします。
  4. 次のコマンドを実行して、アプリを強制的にアプリ スタンバイ モードにします。
        $ adb shell dumpsys battery unplug
        $ adb shell am set-inactive <packageName> true
        
  5. 次のコマンドを使用して、アプリを起動するシミュレーションを行います。
        $ adb shell am set-inactive <packageName> false
        $ adb shell am get-inactive <packageName>
        
  6. 復帰後のアプリの動作を監視します。アプリがスタンバイ モードから正常に復帰することを確認します。特に、アプリの通知とバックグラウンド ジョブが想定どおりに機能するかどうかを確認します。

免除が認められるユースケース

次の表に、いくつかのユースケースと、これらの状況でアプリが ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS インテント アクションを使用できるかどうかを示します。一般に、アプリがこれらの例外に該当することはありません。ただし、アプリのコア機能が Doze またはアプリ スタンバイによって損なわれる場合や、アプリが FCM RemoteNotification メッセージを使用できない技術的な理由がある場合は例外です。

詳細については、その他のユースケースのサポートをご覧ください。

タイプ ユースケース FCM 使用の可否 免除は可能ですか? メモ
インスタント メッセージ、チャット、通話アプリ デバイスが Doze モードのとき、またはアプリがアプリ スタンバイ モードのときに、ユーザーにリアルタイム メッセージを配信する必要がある。 FCM を使用できます。 受け入れできません FCM の RemoteNotification メッセージを使用してアプリを復帰させ、ネットワークにアクセスします。
はい。ただし、FCM RemoteNotification メッセージは使用していません。
インスタント メッセージ、チャット、通話アプリ、エンタープライズ VOIP アプリ。 いいえ。別のメッセージ サービスに技術的に依存しているため、または Doze とアプリ スタンバイによってアプリのコア機能が損なわれるため、FCM を使用できません。 許可される
安全アプリ。 ユーザーとその家族の安全を守るアプリ。 該当する場合のみ記入 許可される
タスク自動化アプリ。 アプリのコア機能が、インスタント メッセージ、音声通話、新しい写真の管理などの自動アクションのスケジュール設定である。 該当する場合のみ記入 許可される
周辺機器のコンパニオン アプリ。 アプリのコア機能が、周辺機器にインターネット アクセスを提供する目的で、周辺機器との永続的な接続を維持することである。 該当する場合のみ記入 許可される
アプリが、同期のために周辺機器に定期的に接続する必要があるだけの場合、または標準の Bluetooth プロファイル経由で接続されたデバイス(ワイヤレス ヘッドフォンなど)に接続する必要があるだけの場合。 該当する場合のみ記入 登録不可