Android-PowerManager WakeLock

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()
  1. Background Threadにかかる作業をする前に、WakeLockを取得する必要があります。 newWakeLock(level, name)でWakeLockを生成することができ、 acquire()を呼び出すと、WakeLockを獲得することになります。
  2. かかるタスクを処理します。
  3. 作業がすべて完了したら 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()
}
  1. acquire(60 * 1000)で60秒後にもWakeLockが解除されない場合、自動的に解除されるようにTimeoutを設定しました。
  2. タスクを実行します。
  3. 作業が完了したときWakeLockを解除します。 isHeld()はWakeLockを獲得しているときにtrueを返します。

Related Posts

codechachaCopyright ©2019 codechacha