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