Androidはデバイスが使用されていないときにバッテリーが消耗しないように節電モードに移行されます。省電力モードに入ると、画面も消えCPUも停止します。
もし私のアプリのBackground Processで時間のかかる作業を処理していたが、省電力モードに入りた場合ProcessがSleep状態に陥って何もしないことがあります。このようなときは、WakeLockを利用して、問題を解決することができます。
WakeLockは、デバイスがSleep状態に陥らないようです。ジョブを処理する前に、WakeLockを得て、すべての作業が完了したの後にWakeLockをシステムに返された場合、ジョブが処理されている中に、CPUが停止しなくなります。
WakeLock権限
WakeLockを使用するには、AndroidManifestには、次の権限を追加する必要があります。
<uses-permission android:name="android.permission.WAKE_LOCK" />
アプリがインストールされていると同時に権限を持つInstall Permissionので、Manifestに宣言するだけです。
WakeLock例
次はWakeLockを利用して、どのような操作を処理する例です。
// 1. Aquire wakelock
val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock: PowerManager.WakeLock =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag")
wakeLock.acquire()
// 2. Perform your tasks
// 3. Release wakelock
wakeLock.release()
- Background Threadにかかる作業をする前に、WakeLockを取得する必要があります。
newWakeLock(level, name)
でWakeLockを生成することができ、acquire()
を呼び出すと、WakeLockを獲得することになります。 - かかるタスクを処理します。
- 作業がすべて完了したら
release()
でWakeLockを返す必要があります。返さないデバイスは目覚めている状態になってバッテリーが消耗します。
WakeLock Level
newWakeLock()
の引数として渡されるLevelは、次のようなものがあります。
Flag Value | CPU | Screen | Keyboard |
---|---|---|---|
PARTIAL_WAKE_LOCK | On | Off | Off |
SCREEN_DIM_WAKE_LOCK | On | Dim | Off |
SCREEN_BRIGHT_WAKE_LOCK | On | Bright | Off |
FULL_WAKE_LOCK | On | Bright | Bright |
Android DeveloperのPowerManagerの説明をまとめました。 DeprecatedされたFLAGについては、サイトから直接確認してください。
- PARTIAL_WAKE_LOCK:screenとkeyboardのbacklightはオフになり、CPUは動作します。ユーザーがPowerボタンを押してscreenを切ってもCPUはWakeLockがreleaseされるまで動作します
- SCREEN_DIM_WAKE_LOCK:このオプションは、Deprecatedされ、代わりに
WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
を利用するようにします - SCREEN_BRIGHT_WAKE \ _LOCK:このオプションは、Deprecatedされ、代わりに
WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
を利用するようにします - FULL_WAKE_LOCK:このオプションは、Deprecatedされ、代わりに
WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
を利用するようにします
WakeLock Timeout
上記の例では、明示的に release()
を呼び出す必要がありました。誤って release()
を抜いて食べると、デバイスは常にオンになり、バッテリは急速に消耗されます。
acquire(timeout)
を使用すると、引数として渡された時間の後に release()
が呼び出されWakeLockが自動的に解除されます。誤って release()
を呼び出していない場合を防ぐことができます。 (timeoutの時間単位はmillisecondです。)
そのため、Timeoutは、ジョブが処理され、予想される時間よりも十分に多くの時間を入れてくれれば良いです。また、仕事を終えた後、明示的にWakeLockを解除するように実装する必要がバッテリーを節約することができます。
// 1. Aquire wakelock
val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock: PowerManager.WakeLock =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag")
wakeLock.acquire(60 * 1000) // 60 sec
// 2. Perform your tasks
// 3. Release WakeLock
if (wakeLock.isHeld) {
wakeLock.release()
}
acquire(60 * 1000)
で60秒後にもWakeLockが解除されない場合、自動的に解除されるようにTimeoutを設定しました。- タスクを実行します。
- 作業が完了したときWakeLockを解除します。
isHeld()
はWakeLockを獲得しているときにtrueを返します。
Related Posts
- エラー解決:android gradle plugin requires java 11 to run. you are currently using java 1.8.
- Android - コルーチンとRetrofitによる非同期通信の例
- Android - コルーチンでURL画像を読み込む
- Android - 振動、Vibrator、VibrationEffectの例
- Some problems were found with the configuration of task
- Query method parameters should either be a type that can be converted into a database column or a List
- UbuntuでAndroid 12オープンソースをダウンロードしてビルド
- Android - ViewModelを生成する方法
- Android - Transformations.map(), switchMap() の違い
- Android-Transformations.distinctUntilChanged()소개
- Android - TabLayoutの実装方法(+ ViewPager2)
- Android - 携帯電話の電話番号を取得する方法
- Android 12 - Splash Screens
- Android 12 - インクリメンタルインストール
- Android - adbコマンドでbugreportログファイルの抽出
- Android - adbコマンドでAppデータを削除する
- Android - adbコマンドでアプリ無効化、有効化
- Android - adbコマンドで特定のパッケージのPIDを検索
- Android - adbコマンドでパーミッションGrantまたはRevoke
- Android - adbコマンドで特定のパッケージのプロセスの終了
- Android - adbコマンドでapkのインストール、削除、
- Android - adb push、pullでファイルのコピー、ダウンロード
- Android - adbコマンドでscreen capture保存
- Android - adbコマンドでSystemアプリの削除、インストール
- Android - adbコマンドでsettings value確認、変更、
- Android 12 - IntentFilterのexported明示的な宣言
- Android - adbコマンドで工場出荷時の(Factory reset)
- Android - adb logcatコマンドでログ出力
- Android - adbコマンドでメモリダンプ(dump-heap)
- Android - adbコマンドでApp強制終了(force-stop)
- Android - adbコマンドでServiceの実行、終了
- Android - adbコマンドでActivity実行
- Android - adbコマンドでBroadcast配信
- Android - PackageManagerにPackage情報を取得する
- Android - ACTION_BOOT_COMPLETEDイベント受信