Android 9(API レベル 28)では、デバイスの電源管理を改善する新機能が導入されています。これらの変更と、以前のバージョンにすでに存在していた機能を組み合わせることで、システム リソースを最も必要とするアプリにシステム リソースを提供することが可能になります。
電源管理機能は、次の 2 つのカテゴリに分類されます。
- アプリ スタンバイ バケット
- システムは、ユーザーの使用パターンに基づいて、CPU やバッテリーなどのデバイス リソースへのアプリのアクセスを制限します。これは Android 9 の新機能です。
- バッテリー セーバーの改善
- バッテリー セーバーをオンにすると、システムによってすべてのアプリに制限が適用されます。これは Android 9 で改善された既存の機能です。
アプリ スタンバイ バケット
Android 9 には、新しいバッテリー管理機能であるアプリ スタンバイ バケットが導入されています。アプリ スタンバイ バケットは、アプリの最終利用日時と使用頻度に基づいて、リソースに対するアプリのリクエストをシステムが優先順位付けするのに役立ちます。各アプリは、その使用パターンに基づいて 5 つの優先度バケットのいずれかに振り分けられます。システムは、各アプリが入っているバケットに基づいて、そのアプリで使用できるデバイス リソースを制限します。
この 5 つのバケットでは、次の特性に基づいてアプリをグループに優先順位付けします。
- 有効
ユーザーが現在アプリを使用している場合、そのアプリはアクティブ バケットに入ります。次に例を示します。
- アプリがアクティビティを開始した
- アプリがフォアグラウンド サービスを実行している
- フォアグラウンド アプリで使用されるコンテンツ プロバイダに関連付けられた同期アダプターがある
- ユーザーがアプリからの通知をクリックする
アプリがアクティブ バケット内にある場合、システムはアプリのジョブ、アラーム、FCM メッセージに制限を加えません。
- ワーキング セット
アプリが頻繁に実行されているものの、現在アクティブでない場合、ワーキング セット バケットに入ります。たとえば、ユーザーが毎日起動するソーシャル メディア アプリは、ワーキング セットに入っている可能性が高くなります。アプリが間接的に使用される場合も、ワーキング セット バケットに昇格されます。
アプリがワーキング セット内にある場合、システムはジョブの実行とアラームのトリガーの機能に緩やかな制限を加えます。詳しくは、電源管理に関する制限をご覧ください。
- 高頻度
アプリが毎日ではなくとも定期的に使用される場合、高頻度バケットに入ります。たとえば、ユーザーがジムで実行するワークアウト記録アプリは、高頻度バケットに入っている可能性があります。
アプリが高頻度バケット内にある場合、システムは、ジョブの実行とアラームのトリガーの機能に対して強い制限を加え、優先度の高い FCM メッセージにも上限を適用します。詳しくは、電源管理に関する制限をご覧ください。
- 低頻度
アプリがあまり使用されない場合、低頻度バケットに入ります。たとえば、ユーザーが滞在中にしか実行しないホテルアプリは低頻度バケットに入ります。
アプリが低頻度バケット内にある場合、システムは、ジョブの実行、アラームのトリガー、優先度の高い FCM メッセージの受信の機能に厳格な制限を加えます。また、アプリのインターネットに接続する機能も制限します。詳しくは、電源管理に関する制限をご覧ください。
- 思わない
インストールされているが実行されなかったアプリは、never バケットに割り当てられます。システムはこのようなアプリに厳しい制限を課しています。
システムは各アプリを優先度バケットに動的に割り当て、必要に応じて再割り当てします。システムは、プリロードされたアプリを利用して各アプリが使用される可能性を機械学習で判断し、適切なバケットにアプリを割り当てます。このシステムアプリがデバイスに存在しない場合、デフォルトで最終利用日時に基づいてアプリを並べ替えます。よりアクティブなアプリほどアプリの優先度が高くなるバケットが割り当てられ、アプリがより多くのシステム リソースを利用できるようになります。特に、このバケットによって、アプリのジョブの実行頻度、アプリがアラームをトリガーする頻度、アプリが優先度の高い Firebase Cloud Messaging (FCM)メッセージを受信できる頻度が決まります。これらの制限は、デバイスがバッテリーで動作している間にのみ適用されます。デバイスの充電中は、システムはアプリにこれらの制限を適用しません。
どのメーカーも、アクティブでないアプリをバケットに割り当てる方法について独自の基準を設定できます。アプリがどのバケットに割り当てられるかに影響を与えようとしないでください。それよりも、アプリがどのようなバケットにあっても適切に動作することが重要です。アプリは新しいメソッド UsageStatsManager.getAppStandbyBucket()
を呼び出すことで、現在どのバケットにあるかを確認できます。
ベスト プラクティス
アプリがすでに Doze とアプリ スタンバイのベスト プラクティスに従っている場合、新しい電源管理機能の処理は難しくありません。ただし、以前は正常に機能していたアプリの動作に、問題が発生する場合があります。
- システムを操作してアプリをいずれかのバケットに入れようとしないでください。システムのバケット化方法は変わる可能性があるため、どのデバイス メーカーも、独自のアルゴリズムで独自のバケットアプリを作成できます。そのようなことはせず、アプリはどのバケット内にあっても適切に動作することが重要です。
- アプリにランチャー アクティビティがない場合、アクティブ バケットに昇格することはありません。そのようなアクティビティを持たせるようアプリを再設計することをおすすめします。
- アプリの通知が操作できない場合、ユーザーは通知を操作しても、アプリのアクティブ バケットへの昇格をトリガーできません。この場合は、適切な通知を再設計して、ユーザーからの応答を許可できます。ガイドラインについては、マテリアル デザインの通知のデザイン パターンをご覧ください。
同様に、優先度の高い FCM メッセージを受信してもアプリに通知が表示されない場合、ユーザーはアプリを操作してアクティブ バケットに昇格できません。実際は、優先度の高い FCM メッセージを使用するのは、ユーザーに通知をプッシュしたいときだけなので、このような状況は発生しません。ユーザー操作をトリガーしない FCM メッセージを誤って高優先度としてマークすると、他の悪影響をもたらす可能性があります。たとえば、アプリが割り当てを使い果たし、真に緊急の FCM メッセージが通常の優先度として扱われる可能性があります。
注: ユーザーが通知を繰り返し閉じると、システムはその通知を今後ブロックするかどうか選択できます。アプリをアクティブ バケットに置いておくためだけに、ユーザーに不要な通知を送信しないでください。
アプリが複数のパッケージに分割されている場合、それらのパッケージは異なるバケットに入っており、アクセスレベルが異なる可能性があります。このようなアプリをさまざまなバケットにパッケージを割り当ててテストし、アプリが適切に動作することを確認する必要があります。
バッテリー セーバーの改善
Android 9 では、バッテリー セーバー モードに複数の改善が行われています。 適用される詳細な制限はデバイス メーカーが決定します。たとえば、AOSP ビルドでは次の制限が適用されます。
- システムは、アプリがアイドル状態になるのを待たずに、積極的にアプリをアプリ スタンバイ モードにします。
- バックグラウンド実行の上限は、対象 API レベルに関係なく、すべてのアプリに適用されます。
- 画面がオフになると、位置情報サービスが無効化される場合があります。
- バックグラウンド アプリは、ネットワークにアクセスできません。
さらに、デバイス固有の消費電力最適化が他にもあります。詳細については、電源管理に関する制限のページをご覧ください。
通常どおり、バッテリー セーバーがアクティブな状態でアプリをテストすることをおすすめします。バッテリー セーバーは、デバイスの [設定] > [バッテリー セーバー] 画面で手動でオンにできます。
テストとトラブルシューティング
新しい電源管理機能は、アプリが Android 9 をターゲットとするかどうかにかかわらず、Android 9 デバイスで実行されているすべてのアプリに影響します。このようなデバイス上でアプリが正しく動作するか必ず確認してください。
さまざまな条件下でアプリの主なユースケースをテストして、電源管理機能の相互作用を確認してください。Android Debug Bridge コマンドを使用すると、一部の機能のオン / オフを切り替えることができます。
Android Debug Bridge コマンド
Android Debug Bridge シェルコマンドを使用して、いくつかの電源管理機能をテストできます。
ADB を使用してデバイスを Doze モードにする方法については、Doze モードとアプリ スタンバイ モードでテストするをご覧ください。
アプリ スタンバイ バケット
ADB を使用すると、アプリをアプリ スタンバイ バケットに手動で割り当てることができます。アプリのバケットを変更するには、次のコマンドを使用します。
$ adb shell am set-standby-bucket packagename active|working_set|frequent|rare
このコマンドを使用して、複数のパッケージを一度に設定することもできます。
$ adb shell am set-standby-bucket package1 bucket1 package2 bucket2...
アプリが所属しているバケットを確認するには、次のコマンドを実行します。
$ adb shell am get-standby-bucket [packagename]
このコマンドで、packagename パラメータを渡さなかった場合、すべてのアプリのバケットがリストアップされます。また、新しいメソッドの UsageStatsManager.getAppStandbyBucket()
を呼び出すと、アプリの実行時にバケットを調べることができます。
バッテリー セーバー
低消費電力状態でアプリがどのように動作するかテストするコマンドがいくつか用意されています。
デバイスの電源を取り外すシミュレーションを行うには、次のコマンドを使用します。
$ adb shell dumpsys battery unplug
低消費電力状態でデバイスがどのように動作するかテストするには、次のコマンドを使用します。
$ adb shell settings put global low_power 1
テストが完了したら、次のコマンドを使用して手動のデバイス設定を元に戻すことができます。
$ adb shell dumpsys battery reset