AndroidのappWidget作成時に行っておくべき消費電力対策についてのまとめ(その1)

先日記載したセンテンスばらばらの試行記録を消費電力対策の部分だけ整理しました。
今後も、何か見つけたらエントリ起こしていきたいと思います。

消費電力に対して影響を与えうる内容。

  1. AppWidgetProviderの更新周期をres/xml/*.xml側のandroid:updatePeriodMillis定義によって行っている。

そのことによるメリット

  1. 実装が非常に楽。(onUpdateをオーバーライドして実装を記述するだけでよい)

そのことによって起こる現象とバッテリーへの影響

  1. Homeがアクティブ状態になくても更新リクエストを繰り返す。
  2. そのため、デバイスがスリープ状態でも更新処理が走り、電池を消耗する。

対策方法概要

  1. res/xml/*.xml側のandroid:updatePeriodMillisに値ゼロ[0]を指定し、システムからのonUpdate呼び出しを停止する。
  2. AppWidgetProvider.onUpdateの呼び出しをAppWidgetProvideronReceive側から呼び出し行うように処理を変更する
  3. onUpdate内にAlermManagerを作成して、指定時間で自分自身にintentを投げるように設定する。*1
  4. この際、投げるintentには必ず、ウィジェットIDを添付する。

PublicMethodsの呼ばれ方比較

android:updatePeriodMillisに0以外の値を定義した場合の動き
  1. Widget配置時
    1. onEnabled => onReceive
  2. updatePeriodMillis周期時
    1. onReceive
  3. Widget解除時
    1. onDisabled => onDeleted
android:updatePeriodMillisに0を定義した場合の動き
  1. Widget配置時
    1. onEnabled => onReceive
  2. updatePeriodMillis周期時
    1. 0指定のため、イベント起動がなし
  3. Widget解除時
    1. onDisabled => onDeleted

実装時注意点

  1. SowftwareUpdate、最初の画面へのアクティブ化等の際、onUpdateは必ず1回呼ばれるので、起動、初期化等は常にここで行えばよい。
  2. AlermManaerは電源OFF、アプリケーションのバージョンUp/アンインストール時などに内容が消える。影響があるのは電源OFFだけなので、Intent.ACTION_BOOT_COMPLETEDに対する対応も必要。*2
  3. appWidgetProviderへの通知をAlarmManagerで行う場合、
    1. PendingIntentを用いてIntentを設定する必要がある。
    2. PendingIntentへAppWidgetProider向けのIntentを定義するためのメソッドはgetBroadcastである。
    3. AlermManaerを定義する場合、引数としてAlarmManager.ELAPSED_REALTIMEまたはAlarmManager.RTCを指定する必要がある。*3
    4. AppWidgetProvider.onReceiveからAppWidgetProvider.onUpdateを起動する場合、投げるIntentにウィジェットIDを付ける必要あり
    5. ウィジェットIDは最初のonUpdateの最初の呼び出し時に第3引数として入ってくる物から得る。この値のUri化は下記の通り
    6. onReceive(Context context,Intent intent)からonUpdateを起動する場合、onUpdate(context, AppWidgetManager.getInstance(context), ウィジェットIDを配列化した値)で行える。

思いついたのはこのくらいかな〜。

次回は1アプリなのに、複数のサイズ定義が可能なウィジェットの作成方法をドキュメント化したいと思いまーす。

*1:ここをServiceでやろうとすると、Android自体がリソースをあけるために行うリソース整理作業のため、Service自体がsystemにより殺されてしまっている場合がある。

*2:下記参照: http://www.taosoftware.co.jp/blog/2009/03/alarmmanager_4.html

*3:_WAKEUP付きを指定してしまうと、結局、スリープ中も強制呼び出しがかかるので注意すること。