page.title=電池残量と充電状態の監視
parent.title=電池消費量の最適化
parent.link=index.html

trainingnavtop=true
next.title=ホルダーの装着状態とタイプの特定と監視
next.link=docking-monitoring.html

@jd:body
 
<div id="tb-wrapper"> 
<div id="tb">

<h2>このレッスンの内容</h2>
<ol>
  <li><a href="#DetermineChargeState">現在の充電状態を特定する</a></li>
  <li><a href="#MonitorChargeState">充電状態の変化を監視する</a></li>
  <li><a href="#CurrentLevel">現在の電池残量を特定する</a></li>
  <li><a href="#MonitorLevel">電池残量の大きな変化を監視する</a></li>
</ol>

<h2>関連項目</h2>
<ul>
  <li><a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>
</ul>

</div> 
</div>
 
<p>バックグラウンド更新が電池消費量に及ぼす影響を抑えるために更新の頻度を変更するには、初めに現在の電池残量と充電状態を調べることをおすすめします。</p>

<p>アプリの更新が電池消費量に及ぼす影響の度合いは、端末の電池残量と充電状態によって異なります。AC 電源から端末を充電しているときは、更新の実行による影響はごくわずかなので、ほとんどの場合は、端末が AC 電源に接続されている限り、更新頻度を最大にして差し支えありません。逆に、端末が電池で駆動しているときは、更新頻度を下げると電池消費量を抑えることができます。</p>

<p>同様に、電池残量を調べると、残量がごくわずかであるときに更新頻度を下げたり、場合によっては停止させたりすることができます。</p>


<h2 id="DetermineChargeState">現在の充電状態を特定する</h2> 
 
<p>初めに、現在の充電状態を特定します。{@link android.os.BatteryManager} によって電池と充電状態に関するすべての詳細情報が sticky {@link android.content.Intent} としてブロードキャストされますが、この中に充電状態が格納されています。</p>

<p>これは sticky インテントであるため、{@link android.content.BroadcastReceiver} を登録する必要はありません。{@code registerReceiver} を呼び出し、{@code null} をレシーバとして渡すだけで（次のコード例を参照）、現在の電池状態のインテントが返されます。ここで実際の {@link android.content.BroadcastReceiver} オブジェクトを渡すこともできますが、このレッスンでは後で更新についての処理を行うので、これは必要ありません。</p>

<pre>IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);</pre>

<p>現在の充電状態に加えて、充電中の場合は USB 経由か AC 充電器経由かを調べることもできます。<p>

<pre>// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = battery.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;</pre>

<p>一般的には、端末が AC 充電器に接続されているときはバックグラウンド更新の頻度を最大にし、USB 経由で充電中のときは頻度を下げ、電池で駆動中のときはさらに頻度を下げます。</p>


<h2 id="MonitorChargeState">充電状態の変化を監視する</h2> 

<p>充電状態は、端末が充電器に接続されたときにすぐに変化するので、充電状態の変化を監視し、その変化に応じて更新の頻度を変更することが重要です。</p>

<p>{@link android.os.BatteryManager} は、端末が電源に接続されたときや接続が解除されたときに、アクションをブロードキャストします。このようなイベントは、アプリが実行中でないときでも受信することが重要です。特にそのイベントが、アプリのバックグラウンド更新を開始するためにアプリを起動させる頻度に影響するものである場合です。したがって、{@link android.content.BroadcastReceiver} をアプリのマニフェスト内で登録し、両方のイベントを受信するために {@link android.content.Intent#ACTION_POWER_CONNECTED} と {@link android.content.Intent#ACTION_POWER_DISCONNECTED} をインテント フィルタ内で定義します。</p>

<pre>&lt;receiver android:name=".PowerConnectionReceiver">
  &lt;intent-filter>
    &lt;action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    &lt;action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
  &lt;/intent-filter>
&lt;/receiver></pre>

<p>関連付けられている {@link android.content.BroadcastReceiver} 実装の中で、前のステップで説明したように、現在の充電状態と充電方法を抽出します。</p>

<pre>public class PowerConnectionReceiver extends BroadcastReceiver {
    &#64;Override
    public void onReceive(Context context, Intent intent) { 
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                            status == BatteryManager.BATTERY_STATUS_FULL;
    
        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
        boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
    }
}</pre>


<h2 id="CurrentLevel">現在の電池残量を特定する</h2> 

<p>状況によっては、現在の電池残量がわかると便利なことがあります。たとえば、電池残量が所定のレベルを下回った場合にアプリのバックグラウンド更新の頻度を下げることができます。</p>

<p>現在の電池残量を調べるには、次に示すように、電池状態のインテントから現在の電池残量と最大量を抽出します。</p>

<pre>int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

float batteryPct = level / (float)scale;</pre>


<h2 id="MonitorLevel">電池残量の大きな変化を監視する</h2> 

<p>電池状態を継続的に監視することは簡単ではありませんが、その必要もありません。</p>

<p>一般的に、電池残量を継続的に監視するほうが、電池への影響はアプリの通常の動作によるものよりも大きくなるため、電池残量の大きな変化のみを監視することをおすすめします。特に、端末が電池残量低下状態に入ったときや、その状態が解消されたときです。</p>

<p>次に示すマニフェストの断片は、ブロードキャスト レシーバの中にあるインテント フィルタ要素からの抜粋です。このレシーバは、端末が電池残量低下状態に入ったときや、その状態が解消されたときに呼び出されます。そのために、{@link android.content.Intent#ACTION_BATTERY_LOW} と {@link android.content.Intent#ACTION_BATTERY_OKAY} を受信します。</p>

<pre>&lt;receiver android:name=".BatteryLevelReceiver">
&lt;intent-filter>
  &lt;action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
  &lt;action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
  &lt;/intent-filter>
&lt;/receiver></pre>

<p>一般的に、電池残量がごくわずかになったときはアプリのバックグラウンド更新をすべて停止することをおすすめします。データがいくら新しくても、端末自体の電源が切れてしまったのではデータを活用できません。</p>

<p>多くの場合、端末の充電という動作が開始するのは、端末がホルダーにセットされるのと同時です。次のレッスンでは、現在のホルダーの状態を特定し、端末のホルダー装着状態の変化を監視する方法を紹介します。</p>

