App Standby — これはAndroidのメカニズムで、使用頻度の低いアプリを待機モードに移行させ、バッテリーを節約するためにバックグラウンドアクティビティを制限します。Doze Mode(デバイスのスリープモード)とは異なり、App Standbyは画面や動きの状態に関係なく、個々のアプリレベルで動作します。Android Developers, 2025の仕様によると、App Standbyは使用頻度の低いアプリのバックグラウンド作業をブロックすることで、エネルギー消費を最大70%削減できます。
重要なポイント
App Standby — これはAndroidのエネルギー管理システムのコンポーネントであり、Android 6.0(API 23)で導入され、Android 9(API 28)で大幅に再設計されました。その役割は、ユーザーがどのアプリをほとんど使用しないかを特定し、それらのバックグラウンドアクティビティ(ネットワークリクエスト、同期、JobScheduler、AlarmManager)を制限することです。Dozeとは異なり、App Standbyは画面やデバイスの動きの状態に依存しません。
システムはアプリを4つのbucket(レベル)に分類します:Active、Working Set、Frequent、Rare。各レベルは、バックグラウンドアクティビティがどの程度制限されるかを決定します。レベルの移行は、アプリの使用パターン(ユーザーがアプリを開く頻度、通知の受信、ウィジェットとのインタラクション)に基づいて自動的に行われます。
App StandbyはDoze Modeと連携して動作しますが、それを置き換えるものではありません。Dozeがデバイスの非アクティブ時にすべてのアプリのバックグラウンドアクティビティを制限するのに対し、App Standbyはデバイスの状態に関係なく特定のアプリを制限します。Rareレベルのアプリは、ユーザーが数日間開いていない場合、電話を積極的に使用している間でも制限を受けます。
Android 9(API 28)以降、GoogleはApp Standby Buckets(数値による正式な分類)を導入しました。システムは機械学習を使用してアプリの次回起動を予測します。モデルがアプリが次の数時間以内に開かれると予測した場合、Active bucketが割り当てられます。予測がまれな使用を示す場合は、Rareが割り当てられます。
App Standbyはbucketを決定するために複数の要素を分析します:ユーザーがアプリを最後に開いてからの時間、インタラクションの頻度(1日/週あたりの起動回数)、FCM通知の受信、デスクトップ上のアクティブなウィジェットの存在、AlarmManagerのサブスクリプション。アプリが使用されない期間が長いほど、bucketは低くなり、制限は厳しくなります。
システムサービスUsageStatsManagerがアプリの使用統計を収集し、それをStandbyController(各アプリのbucketを計算するフレームワークコンポーネント)に送信します。StandbyControllerはシステムイベントも考慮します:アプリの更新後、ユーザーが新機能を評価できるように、bucketは数日間Activeにリセットされます。
重要な特徴:App Standbyはアプリのプロセスを強制終了するのではなく、そのバックグラウンド機能を制限します。ユーザーがアプリとインタラクションしている間(bucket Active)は、アプリは引き続き動作します。ユーザーがアプリを閉じて戻ってこないと、システムは非アクティブの時間をカウントし始め、bucketをWorking SetまたはFrequentに下げることがあります。
FCM high-priorityメッセージを受信すると、アプリのbucketが一時的にActiveまで引き上げられます。これにより、アプリは制限なくタスク(メッセージの処理、データの同期)を実行できます。ただし、処理が完了するとbucketは元の値に戻ります。Googleは、アプリを「生かし続ける」ためではなく、重要な通知を配信するためにこのメカニズムを使用することを推奨しています。
App Standbyはアプリを分類するために4つのレベル(bucket)を使用します。各レベルはバックグラウンドタスクの遅延時間を決定します:レベルが低いほど、遅延が長くなります。システムは過去7〜14日間に収集された使用統計に基づいて、アプリをレベル間で自動的に移動させます。
| Bucket | 説明 | JobScheduler遅延 | ネットワーク |
|---|---|---|---|
| Active | アプリが積極的に使用されている | 遅延なし | 完全アクセス |
| Working Set | 定期的に使用されるが、現在は使用されていない | 最大2時間 | ウィンドウ内 |
| Frequent | 頻繁に使用されるが、毎日ではない | 最大4時間 | ウィンドウ内 |
| Rare | ほとんど使用されないアプリ | 最大24時間 | ウィンドウ内 |
Active — ユーザーが最近インタラクションしたアプリ(起動、通知の受信、ウィジェットの使用)。このbucketには制限はありません:JobSchedulerは即座に実行され、ネットワークは利用可能で、AlarmManagerは正確に動作します。アプリは、ユーザーが数時間インタラクションを停止するまでActiveのままです。
Working Set — アプリは定期的に使用される(週に数回)。バックグラウンドタスクの遅延は最大2時間。Frequent — アプリは月に数回使用される。遅延は最大4時間。両方のレベルで、ネットワークはメンテナンスウィンドウでのみ利用可能で、AlarmManagerは遅延する可能性があります。JobSchedulerは次のウィンドウでタスクを実行します。
Rare — 最も厳格なレベルで、ユーザーが30日以上開いていないアプリに割り当てられます。バックグラウンドタスクの遅延は最大24時間。メンテナンスウィンドウ外ではネットワークが完全にブロックされ、AlarmManagerはsetAndAllowWhileIdle()フラグでのみ動作し、9分間に1回の制限があります。FCM high-priority通知は引き続き配信されますが、bucketを引き上げることはできません。
App Standbyはバックグラウンド操作のいくつかのカテゴリに制限を課します。Dozeとは異なり、App Standbyの制限は画面や充電器の状態に関係なく機能します。開発者は、特にターゲットユーザーがアプリを不定期に使用する場合、これらの制限を考慮してアプリを設計する必要があります。
JobScheduler — App Standbyの影響を受ける主要なAPI。bucketに応じて、タスクの実行は2〜24時間遅延します。内部でJobSchedulerを使用するWorkManager(API 23+)もこれらの遅延の影響を受けます。時間に敏感なタスクには、内部でForeground Serviceを起動し、bucketに依存しないExpedited Workを使用してください。
Working Set、Frequent、Rareのbucketにあるアプリは、いつでも任意のネットワークリクエストを実行できません。システムは、Dozeと同期されたメンテナンスウィンドウ内でのみネットワークアクセスを許可します。重要なデータを送信するには、FCM high-priorityを使用し、その後メンテナンスウィンドウで同期します。
AlarmManagerは、App StandbyでもDozeと同じルールに従います:正確なアラーム(setExact())は遅延され、setAndAllowWhileIdle()は9分間に1回の起動に制限されます。Rare bucketの場合、遅延は最大24時間に達する可能性があり、使用頻度の低いアプリでの正確なタスクスケジューリングにはAlarmManagerは適しません。
除外は、ユーザーのバッテリー設定(手動ホワイトリスト)またはシステムIntent ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONSの2つの方法で取得できます。ただし、Googleは除外へのアクセスを厳しく規制しています — 除外を正当化する十分な理由がないアプリは、Google Playで拒否されるリスクがあります。
ユーザーは、設定 → アプリ → [アプリ] → バッテリー → 最適化 → 最適化しない、の順で特定のアプリの制限を手動で解除できます。これにより、選択したアプリのApp StandbyとDozeの制限が完全に解除されます。開発者はユーザーに指示やシステムダイアログを表示できますが、アプリを強制的に除外リストに追加することはできません。
Foreground Serviceは通知とともに自動的にApp Standbyの一時的な除外を取得します。サービスが実行され通知を表示している間、アプリは実際のレベルに関係なくActive bucketに移行します。サービスが停止すると、bucketは元の値に戻ります。システムの除外を要求せずにバックグラウンド作業を保証する最も信頼性の高い方法です。
Whitelistの要求は、リアルタイムナビゲーション、健康監視、VoIP通話、デバイスセキュリティなど、ミッションクリティカルなバックグラウンド機能を持つアプリにのみ意味があります。ほとんどのアプリでは、Foreground ServiceまたはWorkManagerを使用するだけで十分です。明確な必要性なしに除外を要求するアプリは、Google Playで公開を拒否される可能性があります。
// アプリスタンバイからの除外をリクエスト
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:\${applicationContext.packageName}")
}
// 現在のステータスを確認
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
val isIgnoring = powerManager.isIgnoringBatteryOptimizations(packageName)
テストはADBを介してApp Standbyのアプリを任意のbucketに強制的に設定し、その動作を確認できます。これは、バックグラウンド同期、通知、または定期的な更新に依存するアプリにとって重要です。テストはAndroid 9+の物理デバイスまたはエミュレーターで行う必要があります。
bucketを強制的に設定するには、コマンドadb shell am set-standby-bucket [package] [bucket]を使用します。bucketにはactive、working_set、frequent、rareを指定できます。現在のbucketを確認するには— adb shell am get-standby-bucket [package]。システムはコマンドadb shell dumpsys usagestatsを使用してアプリの長期非アクティブ状態をシミュレートすることもできます。
# アプリにRare bucketを設定
$ adb shell am set-standby-bucket com.example.app rare
# 現在のbucketを表示
$ adb shell am get-standby-bucket com.example.app
# すべてのbucketをActiveにリセット
$ adb shell dumpsys usagestats clear
# システムのすべてのbucketを表示
$ adb shell dumpsys usagestats
Rare bucketを設定した後、以下を確認してください:WorkManagerタスクが24時間以内に実行されるか、AlarmManagerが作動するか、FCM通知が配信されるか、Foreground Serviceが制限なく動作するか。Expedited WorkポリシーのWorkManagerは、Foreground Serviceを使用するため、Rare bucketでも即座に実行される必要があります。通常のWorkManagerタスクはbucketに従って遅延されます。
App Standbyに耐性のあるアプリの開発には、バックグラウンドタスクに対する意識的なアプローチが必要です。基本原則:アプリが常にActive bucketにあると想定しないこと。FrequentおよびRare bucketに特徴的な遅延があっても正しく実行されるようにバックグラウンド作業を設計してください。
Expedited Work(WorkManager 2.7+)は内部でForeground Serviceを起動し、bucketに関係なくタスクを即座に実行します。これは、メッセージの送信、支払い後の同期、着信の処理など、遅延できないタスクに最適な選択肢です。通常のWorkManagerタスクは、bucketを考慮してメンテナンスウィンドウで実行されます。
App Standbyからアプリを起動するには、FCM high-priorityメッセージを使用します。アプリがそのようなメッセージを受信すると、そのbucketは一時的にActiveに引き上げられ、必要なタスク(同期、データ更新)を実行できます。処理が完了すると、bucketは元のレベルに戻ります。
常時稼働のバックグラウンドサービス、WakeLock、または定期的なFCMメッセージでApp Standbyを回避しようとしないでください。Googleはこのような慣行に積極的に対抗しています — アプリはエネルギー消費が多いとマークされ、さらに厳しく制限される可能性があります。定期的なタスクにはWorkManagerを使用し、Foreground Serviceはタスクが実際にユーザーに表示される場合にのみ使用してください。
よくある質問
App Standby — これはAndroidのメカニズムで、アプリを使用頻度に基づいて分類し、使用頻度の低いアプリのバックグラウンドアクティビティを制限します。Dozeとは異なり、App Standbyは画面やデバイスの動きの状態に関係なくアプリレベルで動作します。
4つのレベルがあります:Active(制限なし)、Working Set(最大2時間の遅延)、Frequent(最大4時間の遅延)、Rare(最大24時間の遅延)。レベルはアプリの使用頻度に基づいて自動的に決定されます。
App Standbyはデバイスの状態に関係なく特定の使用頻度の低いアプリを制限します。Doze Modeはデバイスが非アクティブなとき(画面オフ、動きなし)にすべてのアプリを制限します。これらはAndroidの省電力システムで並行して動作し、相互に補完します。
ADBコマンドを使用:adb shell am get-standby-bucket [package]。プログラム的には、Android 9(API 28)以降で利用可能なUsageStatsManager.getAppStandbyBucket()を使用します。メソッドはbucketの数値識別子を返します:10(Active)、20(Working Set)、30(Frequent)、40(Rare)。
WorkManager Expedited Workまたは通知付きのForeground Serviceを使用します。Expedited Workは内部でForeground Serviceを起動し、bucketに関係なく実行を保証します。通常のWorkManagerタスクはアプリの現在のレベルに従って遅延されます。
まとめ
adb shell am set-standby-bucketで各レベルの動作確認ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。