The Android Developer Challenge is back! Submit your idea before December 2.

電源管理

Android 9(API レベル 28)には、端末の電力管理を改善するための新しい機能が導入されています。 これらの変更点と以前のバージョンに既に搭載されていた機能により、システム リソースを最も必要とするアプリでシステム リソースを利用することが可能になります。

電源管理の機能は、次の 2 つのカテゴリに分類されます。

アプリ スタンバイ バケット
システムは、ユーザーの使用パターンに基づいて、CPU や電池などの端末のリソースに対するアプリのアクセスを制限します。 これは Android 9 の新機能です。
バッテリー セーバーの改善点
バッテリー セーバーをオンにすると、システムはすべてのアプリに制限を適用します。 これは既存の機能ですが、Android 9 で改良されています。

注: この変更は、Android 9 を対象にしているかどうかにかかわらず、すべてのアプリに適用されます。

アプリ スタンバイ バケット

Android 9 には、アプリ スタンバイ バケットという新しい電源管理機能が導入されています。 アプリ スタンバイ バケットは、アプリがどれほど最近およびどれくらいの頻度で使用されているかに基づいて、システムがアプリからのリソース要求に優先度を設定するのに役立ちます。 アプリの使用パターンに基づいて、各アプリは 5 つの優先度バケットのいずれかに配置されます。 システムは、各アプリで利用可能な端末リソースを、そのアプリがどのバケットに配置されているかによって制限します。

5 つのバケットは、アプリの優先度を設定し、以下の特性を持つ各グループに分類します。

アクティブ

ユーザーが現在使用しているアプリは、アクティブ バケット内にあります。たとえば、次のような場合です。

  • アプリがアクティビティを起動している
  • アプリがフォアグラウンド サービスを実行中である
  • アプリの同期アダプタがフォアグラウンド アプリによって使用されているコンテンツ プロバイダに関連付けられている
  • ユーザーがアプリからの通知をクリックしている

システムは、アクティブ バケット内にあるアプリのジョブ、アラーム、および FCM メッセージに何の制限も適用しません。

動作中設定

しばしば実行されるが現在アクティブではないアプリは、動作中設定バケット内にあります。 たとえば、ユーザーがほとんど毎日起動するソーシャル メディア アプリは、動作中設定内にあるといえます。 間接的に使用されるアプリも、動作中設定バケットにプロモートされます。

システムは、動作中設定バケット内にあるアプリによるジョブの実行とアラームのトリガーを行う機能に緩い制限を適用します。 詳細は、電力管理の制限事項をご覧ください。

頻繁

必ずしも毎日ではないが定期的に使用されるアプリは、頻繁バケット内にあります。 たとえば、ユーザーがスポーツジムで実行するワークアウト トラッキング アプリは頻繁バケット内にあるでしょう。

システムは、頻繁バケット内にあるアプリによるジョブの実行とアラームのトリガーを行う機能に強い制限を適用し、高優先度の FCM メッセージにも制限を適用します。 詳細は、電力管理の制限事項をご覧ください。

低頻度

あまり使用されないアプリは、低頻度バケット内にあります。 たとえば、ホテルの専用アプリは、ユーザーがそのホテルに滞在中にしか実行しないので、低頻度バケット内にあるでしょう。

システムは、低頻度バケット内にあるアプリによるジョブの実行、アラームのトリガー、および高優先度の FCM メッセージの受信を行うに厳格な制限を適用します。 また、システムはアプリによるインターネット接続も制限します。 詳細は、電力管理の制限事項をご覧ください。

未使用

インストールされたものの実行されたことのないアプリは、未使用バケットに割り当てられます。 システムはこのタイプのアプリに最高の制限を適用します。

システムは各アプリを優先度バケットに動的に割り当て、必要に応じてアプリを割り当て直します。 システムは、各アプリの使用頻度を判断し、その結果をもとにしてアプリは適切なバケットに割り当てるのに、機械学習機能を備えたプリロード済みアプリを使用する場合があります。 そのようなシステムアプリが端末上にない場合は、デフォルトで、どのアプリが一番最近使用されたかに基づいてアプリを分類します。 アプリがアクティブであればあるほど、そのアプリは高優先度が設定されるバケットに割り当てられ、より多くのシステム リソースを使用できるようになります。 特に、バケットの種類によってアプリのジョブが実行される頻度、アプリがアラームをトリガーできる頻度、およびアプリが高優先度 Firebase Cloud Messaging (FCM) メッセージを受信できる頻度が決まります。 上記の制限は端末がバッテリー電源を使用しているときにのみ適用され、端末充電中はシステムが上記の制限をアプリに適用することはありません。

アクティブではないアプリをバケットに割り当てる方法については、各メーカーで独自の基準を設定することができます。 自分の開発したアプリに対するバケット割り当てに影響を及ぼすようなことをすべきではありません。 むしろ、どのバケットに割り当てられてもアプリが良好に動作するようにしてください。 アプリが現在どのバケットに割り当てられているかは、新しいメソッド UsageStatsManager.getAppStandbyBucket() を呼び出すことによって分かります。

注: Doze ホワイトリストに含まれるアプリには、アプリ スタンバイ バケットに基づく制限は適用されません。

ベスト プラクティス

アプリがすでに Doze とアプリ スタンバイのベスト プラクティスに従っているのであれば、新しい電源管理機能の処理は難しくないはずです。 しかし、以前は良好に作動していた一部のアプリの動作がここで問題となることもありえます。

  • システムを操作して、アプリに割り当てられたバケットを変更しようとしてはなりません。 システムのバケット割り当てメソッドは変更される可能性があり、各端末メーカーが独自のアルゴリズムを備えた独自のバケット割り当てアプリを作成している場合もあります。 むしろ、アプリがどのバケット内にあっても適切に動作するようにしてください。
  • ランチャー アクティビティがないアプリはアクティブ バケットにプロモートされません。 そのようなアプリは、再設計してランチャー アクティビティを追加することができます。
  • アプリの通知が操作不能である場合、ユーザーは通知を操作してアプリをアクティブ バケットにプロモートするようトリガーすることはできません。 このような場合、ユーザーから応答できるように該当する通知を設計し直すことができます。 ガイドラインについては、マテリアル デザインの通知設計パターンをご覧ください。
  • 同様に、高優先度 FCM メッセージを受信したときにアプリが通知を表示しない場合、ユーザーはアプリを操作してアクティブ バケットにプロモートする機会を得ることができません。 実際には、高優先度 FCM メッセージの唯一の使用法はユーザーに通知をプッシュすることなので、これは決して発生しないはずです。 FCM メッセージがユーザーの操作をトリガーしない場合に FCM メッセージを不適切に高優先度としてマークしてしまうと、他の悪影響が生じてしまいかねません。たとえば、アプリが割り当て量を使い果たしてしまい、本当に緊急の FCM メッセージが通常の優先度で処理されてしまう結果となる可能性があります。

    注: ユーザーが繰り返し通知を拒否すると、システムから以後その通知をブロックするオプションがユーザーに提供されます。 アプリをアクティブ バケットに維持するだけのために、ユーザーに大量の通知を送信しないでください。

  • アプリが複数のパッケージに分割されている場合、それらのパッケージが別々のバケットに割り当てられ、そのためアクセス レベルが異なる可能性があります。 このようなアプリは必ずテストして、アプリのパッケージが別々のバケットに割り当てられても正常に動作することを確認してください。

バッテリー セーバーの改善点

Android 9 ではバッテリー セーバー モードにいくつかの改良が行われています。 端末メーカーは適用する具体的な制限を決定できます。 たとえば、AOSP ビルドの場合、システムは以下の制限を適用します。

  • システムは、アプリがアイドル状態になるまで待機せず、より積極的にアプリをアプリ スタンバイ モードに移行します。
  • バックグラウンド実行制限は、アプリの対象 API レベルにかかわらず、すべてのアプリに適用されます。
  • 画面がオフになっているとき、ロケーション サービスは無効になる場合があります。
  • バックグラウンド アプリはネットワークにアクセスしません。

また、そのほかにも端末固有の電源最適化機能があります。 詳細は、付録: 電源管理の制限事項 をご覧ください。

常にそうですが、バッテリー セーバーが作動状態にあるときに、アプリをテストするとよいでしょう。 端末の設定 > バッテリー セーバー画面から手動でバッテリー セーバーをオンにすることができます。

テストとトラブルシューティング

電源管理の新しい機能は、Android 9 を対象にしたアプリであるかどうかに関わらず、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
「付録: 電源管理の制限事項」