バッテリー駆動時間はユーザー エクスペリエンスの重要な要素であり、wake lock は大きな役割を果たします。過度に使用していませんか?このブログ投稿では、wake lock とは何か、wake lock を使用する際のベスト プラクティス、Google Play Console の指標を使用してアプリの動作をより深く理解する方法について説明します。
Android Vitals での過度の部分的 wake lock の使用
Google Play Console では、重要業績評価指標として、過度の部分的な wake lock の使用に重点を置いてバッテリー消耗をモニタリングするようになりました。
この機能により、既存の主要な指標の安定性インジケーター(ユーザーが認識する過度のクラッシュと ANR)に加えて、バッテリー効率の重要性が高まります。Google では、過度の wake lock に対し、不正な動作のしきい値を定義しています。2026 年 3 月 1 日以降、タイトルがこの品質基準を満たしていない場合、おすすめなどの目立つ検索サーフェスからタイトルが除外される可能性があります。場合によっては、アプリがバッテリーを過度に消耗する可能性があることをユーザーに知らせる警告がストアの掲載情報に表示されることがあります。
Android Vitals の概要に表示される、過度の wake lock に関する警告。
モバイル デバイスの場合、Android Vitals の指標は、画面がオフで、アプリがバックグラウンドで実行されているか、フォアグラウンド サービスを実行しているときに取得された、除外対象外の wake lock に適用されます。Android Vitals は、次の場合に部分的な wake lock の使用量が過度であると判断します。
- 24 時間以内に wake lock が 2 時間以上保持されている。
- 28 日間の平均で、アプリのセッションの 5% 以上に影響している。
音声、位置情報、JobScheduler のユーザー開始 API によって作成された wake lock は、wake lock の計算から除外されます。
wake lock について
wake lock は、ユーザーがデバイスを操作していないときでも、アプリがデバイスの CPU を動作させ続けることができるメカニズムです。
部分的な wake lock では、画面がオフになっても CPU が動作し続けるため、CPU が低電力の「サスペンド」状態になるのを防ぐことができます。完全な wake lock では、画面と CPU の両方が動作し続けます。
部分的な wake lock を取得する方法は 2 つあります。
- アプリは、特定のユースケースで PowerManager API を使用して wake lock を手動で取得、解放します。多くの場合、これはフォアグラウンド サービス(ユーザーが認識できる操作を目的としたプラットフォーム ライフサイクル API)と組み合わせて取得されます。
- または、別の API によって wake lock が取得され、その API の使用によりアプリに起因するものと見なされる場合もあります。詳しくは、ベスト プラクティスのセクションをご覧ください。
ユーザーが開始した大きなファイルのダウンロードを完了するなどのタスクには wake lock が必要ですが、過度に使用したり不適切に使用したりすると、バッテリーが大幅に消耗する可能性があります。アプリが wake lock を数時間保持したり、適切に解放しなかったりして、アプリを操作していないときでもバッテリーが大幅に消耗するというユーザーからの苦情が寄せられるケースがあります。
wake lock の使用に関するベスト プラクティス
wake lock の過剰な使用をデバッグする方法を説明する前に、wake lock のベスト プラクティスに沿っていることを確認してください。
次の 4 つの重要な質問を検討してください。
1. 代替の wake lock オプションを検討しましたか?
手動で部分的な wake lock を取得することを検討する前に、次の意思決定フローチャートに沿って判断してください。
手動で wake lock を取得するタイミングを決定するためのフローチャート
- 画面をオンのままにする必要があるか?
- はい: 代わりに画面をオンのままにするのドキュメントを参照してください。
- アプリがフォアグラウンド サービスを実行しているか。
- いいえ: wake lock を手動で取得する必要はありません。
- デバイスが一時停止すると、ユーザー エクスペリエンスに悪影響を及ぼすか?
- いいえ: たとえば、デバイスが復帰した後に通知を更新する場合、wake lock は必要ありません。
- はい: 外部デバイスとの通信が継続しているなど、デバイスが一時停止しないようにすることが重要な場合は、続行します。
- デバイスをスリープ状態にしないようにする API がすでに存在しているか?
- 他の API によって作成された wake lock を特定するのドキュメントを参照して、他の API によって wake lock が作成されるシナリオを特定できます。たとえば、LocationManager などの API によって wake lock が作成されるシナリオを特定できます。
- API が存在しない場合は、最後の質問に進みます。
- 上記の質問にすべて回答し、代替手段がないと判断した場合は、手動で wake lock を取得します。
2. wake lock に正しい名前を付けているか。
wake lock を手動で取得する場合、デバッグのために適切な名前を付けることが重要です。
- 名前にメールアドレスなどの個人を特定できる情報(PII)を含めないようにします。PII が検出されると、wake lock は
_UNKNOWNとしてログに記録され、デバッグの妨げになります。 - クラス名やメソッド名を使用してプログラムで wake lock に名前を付けないでください。Proguard などのツールによって難読化される可能性があるためです。代わりに、ハードコードされた文字列を使用します。
- wake lock タグにカウンタまたは固有識別子を追加しないでください。システムが名前で使用状況を集計できるように、wake lock が実行されるたびに同じタグを使用する必要があります。これにより、異常な動作を検出しやすくなります。
3. 取得した wake lock は常に解放されますか?
wake lock を手動で取得する場合は、wake lock のリリースが常に実行されるようにしてください。wake lock を解除しないと、バッテリーが大幅に消耗する可能性があります。
たとえば、processingWork() の処理中にキャッチされない例外がスローされると、release() 呼び出しが実行されない可能性があります。代わりに、try-finally ブロックを使用することで、例外が発生した場合でも wake lock が解放されるようにできます。
また、wake lock にタイムアウトを追加して、特定の期間が経過した後に解放されるようにすることで、無期限に保持されるのを防ぐことができます。
fun processingWork() {
wakeLock.apply {
try {
acquire(60 * 10 * 1000) // timeout after 10 minutes
doTheWork()
} finally {
release()
}
}
}4. 起動頻度を減らすことはできますか?
定期的なデータ リクエストの場合、アプリがデバイスを復帰させる頻度を減らすことが、バッテリーを最適化するうえで重要です。ウェイクアップの頻度を減らす例を次に示します。
- WorkManager: PeriodicWorkRequest の定期的な間隔を長くします。
- SensorManager: リスナーの登録時に maxReportLatencyMs を指定して、バッチ処理を活用します。
- Fused Location Provider:
- getLastLocation を使用して、キャッシュに保存されている最新の位置情報を取得することで、位置情報の取得頻度を減らします。
- バッテリー消費の少ない更新方法には、setPriority(PRIORITY_PASSIVE) を使用します。
- また、setMinUpdateIntervalMillis で最小更新間隔を設定することで、位置情報のバッチ処理メカニズムを利用できます。
詳しくは、wake lock のベスト プラクティスに関するドキュメントをご覧ください。
過度の wake lock 使用のデバッグ
最善の意図があっても、wake lock の過剰な使用が発生する可能性があります。アプリが Google Play Console でフラグ付けされた場合は、次の手順に沿ってデバッグします。
Google Play Console での最初の身元確認
Android Vitals の過度の部分 wake lock ダッシュボードには、アプリに関連付けられた免除対象外の wake lock 名の内訳が表示され、影響を受けたセッションと期間が示されます。ドキュメントを参照して、wake lock 名がアプリによって保持されているか、別の API によって保持されているかを特定してください。
Android Vitals の過度の部分的な wake lock ダッシュボードを下にスクロールして、内訳セクションで過度の wake lock タグを表示したところ。
ワーカー / ジョブによって保持されている過剰な wake lock のデバッグ
ワーカーが保持する wake lock は、次の wake lock 名で識別できます。
*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
ワーカーが保持する wake lock 名のバリエーションの完全なリストについては、ドキュメントをご覧ください。これらの wake lock をデバッグするには、Background Task Inspector を使用してローカルでデバッグするか、getStopReason を使用して現場で問題をデバッグします。
Android Studio Background Task Inspector
Background Task Inspector のスクリーン キャプチャ。頻繁に再試行して失敗しているワーカー「WeatherSyncWorker」を特定できています。
WorkManager の問題をローカルでデバッグするには、エミュレータまたは接続されたデバイス(API レベル 26 以降)でこのツールを使用します。ワーカーとそのステータス(完了、実行中、キューに登録済み)のリストが表示され、詳細を調べてワーカー チェーンを把握できます。
たとえば、システム制限に達したためにワーカーが頻繁に失敗したり、再試行したりしているかどうかを把握できます。
詳しくは、Background Task Inspector のドキュメントをご覧ください。
WorkManager getStopReason
過剰な wake lock が発生しているワーカーを現場でデバッグするには、WorkManager 2.9.0 以降で WorkInfo.getStopReason() を使用するか、JobScheduler の場合は SDK 31 以降で利用可能な JobParameters.getStopReason() を使用します。
この API は、ワーカーが停止した理由(STOP_REASON_TIMEOUT、STOP_REASON_QUOTA など)をログに記録し、ランタイム期間の枯渇による頻繁なタイムアウトなどの問題を特定するのに役立ちます。
backgroundScope.launch {
WorkManager.getInstance(context)
.getWorkInfoByIdFlow(workRequest.id)
.collect { workInfo ->
logStopReason(workRequest.id, workInfo?.stopReason)
}
}詳しくは、タスク スケジューリング API のバッテリー使用量を最適化するをご覧ください。
その他の種類の過度の wake lock をデバッグする
手動で保持された wake lock や、wake lock を保持する API が関与する、より複雑なシナリオでは、システム トレース コレクションを使用してデバッグすることをおすすめします。
システム トレースの収集
システム トレースは、一定期間のシステム アクティビティの詳細な記録をキャプチャする強力なデバッグツールです。CPU の状態、スレッド アクティビティ、ネットワーク アクティビティ、バッテリー関連の指標(ジョブの継続時間や wake lock の使用状況など)に関する分析情報を提供します。
システム トレースをキャプチャするには、次の方法があります。
- システム トレース コマンドライン ツールを使用する
- Android Studio CPU Profiler を使用する
- Perfetto UI の使用
- 開発者向けオプションから直接、デバイス上でトレースを手動で記録する。
Perfetto UI の [Android アプリ & svcs] タブで、[power:PowerManagement] Atrace カテゴリを有効にします。
どの方法を選択した場合でも、デバイスの状態トラックを表示できるように、「power:PowerManagement」Atrace カテゴリを収集することが重要です。
Perfetto UI の検査と SQL 分析
システム トレースは、Perfetto UI で開いて検査できます。トレースを開くと、さまざまなプロセスがタイムライン上に可視化されます。このガイドでは、「デバイスの状態」のトラックに焦点を当てます。
[Device State] の下にある [Top app]、[Screen state]、[Long Wake locks]、[Jobs] などのトラックを固定して、長時間実行されている wake lock スライスを視覚的に特定します。
各ブロックには、イベントの名前、イベントの開始日時、終了日時が表示されます。Perfetto では、これをスライスと呼びます。
複数のトレースをスケーラブルに分析するには、Perfetto の SQL 分析を使用します。SQL クエリを使用すると、すべての wake lock を期間順に並べ替えて、過剰な使用の主な原因を特定できます。
次のクエリの例では、システム トレースで発生したすべての wake lock タグを合計し、合計時間で並べ替えています。
SELECT slice.name as name, track.name as track_name,SUM(dur / 100000) as total_dur_ms FROM slice JOIN track ON slice.track_id = track.id WHERE track.name = 'WakeLocks'GROUP BY slice.name, track.name ORDER BY total_dur_ms DESC
ProfilingManager を使用してフィールド内トレースを収集する
再現が難しい問題については、ProfilingManager(SDK 35 で追加)というプログラム API を使用して、開始トリガーと終了トリガーでフィールドのシステム トレースを収集できます。プロファイル収集の開始と終了のトリガー ポイントをより細かく制御でき、システムレベルのレート制限を適用してデバイスのパフォーマンスへの影響を防ぎます。
フィールド システム トレース収集を実装する方法の詳細については、ProfilingManager のドキュメントをご覧ください。これには、プログラムでトレースをキャプチャする方法、プロファイリング データを分析する方法、ローカル デバッグ コマンドを使用する方法が含まれます。
ProfilingManager を使用して収集されたシステム トレースは、手動で収集されたものと似ていますが、システム プロセスや他のアプリのプロセスはトレースから削除されます。
まとめ
Android Vitals の過度の部分的な wake lock 指標は、バッテリーの消耗を抑え、アプリの品質を向上させるためにデベロッパーをサポートする継続的な取り組みのほんの一部にすぎません。
wake lock を理解して適切に実装することで、アプリのバッテリー パフォーマンスを大幅に最適化できます。代替 API の活用、wake lock のベスト プラクティスの遵守、Background Task Inspector、システム トレース、ProfilingManager などの強力なデバッグツールの使用は、Google Play でアプリを成功させるための鍵となります。
-
サービスに関する最新情報Unity は世界中のモバイルタイトルの半数以上を支えており、第一印象が重要です。ゲーム デベロッパーにとって、スムーズで信頼性の高いプレーヤー オンボーディング エクスペリエンスは、1 日目の維持率と長期的なエンゲージメントを促進するために不可欠です。
Michelle Martin • 所要時間: 1 分 -
サービスに関する最新情報自宅での完全な没入感から、外出先での一目でわかるエクスペリエンスまで、Android XR を基盤に構築することで、空間アプリケーションのあらゆる場面でユーザーにリーチできます。Android Developer Summit で、XREAL AURA のリリースというエキサイティングなマイルストーンを達成しました。
Amy Zeppenfeld, Vinny DaSilva • 所要時間: 3 分 -
サービスに関する最新情報インテリジェンスの時代において、ユーザーはアプリをタップするだけでなく、高度な目標を表現し、Gemini のような AI エージェントが、デバイス上の複数のアプリにまたがることもあるマルチステップのワークフローを完了することを期待しています。
Jingyu Shi • 所要時間: 4 分
Android 開発に関する最新の分析情報を毎週メールでお届けします。