アプリを作る際、Low Batteryによる端末終了と、Shutdownによる終了の処理が必要になりますので、調べてみました。
Low Batteryの処理
バッテリーステータスは、Broadcast Intentで、アプリに飛んできます。簡単に図にまとめます。(FULL/NORMAL/LOWは、便宜的につけたステータスです)
今回のようなシチュエーションでは、Low Batteryによる処理をしますので、ACTION_BATTERY_LOWのBroadcast Intentを捕まえれば・・・ではないです。
このACTION_BATTERY_LOWは、機種にもよりますが、バッテリー残量が15%になると発行されるようです。
そうです、ぜんぜんLow Batteryとは言えません。このIntentが発行されるタイミングは、まさに、端末が「バッテリー残量が少ないです」って割り込みのポップアップを出してくるタイミングです。
これはただのユーザへの警告ですので、アプリとしてここでLow Batteryの終了を始めるのは、気が早い。
さらに、アプリ起動時に、このBroad cast Intentが発行済みの場合、(つまり残量15%以下)、アプリには通知されません。
アプリが知りたいのは、バッテリー残量が0%になった、もう端末終了するよ〜の状態です。
Emulatorと、Xperiaで、Low Batteryにしてみたところ、ACTION_BATTERY_CHANGEDで、EXTRA_LEVELが0で通知され、その直後にACTION_SHUTDOWNが飛んでくる動作になっていました。
ということで、EXTRA_LEVEL=0を検出するか、ACTION_SHUTDOWNを受ける動作をすればよい、ということになります。
ただ、そのACTION_SHUTDOWNも、何も考えずに使えるわけでもなさそうなので、別エントリで調査結果を書きます。
Android アプリの終了処理:Low BatteryとShutdown(2)に続きます
Battery周りの動作を確認したコードを晒しておきます。
ちなみにBroadcastReceiverの作り方など、こちらを参考にさせてもらっています。
package test.sample.battery;
import android.app.Activity;
import android.os.Bundle;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class BatteryTestActivity extends Activity {
private static final String TAG = "BatteryTest";
private final static int msgBatteryLow = 1;
private final static int msgShutdown = 2;
private final static int msgBatteryChanged = 3;
private final static int msgBatteryOK = 4;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startSystemMonitor();
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDestroy();
stopSystemMonitor();
}
@Override
protected void onPause() {
Log.d(TAG, "onPause()");
super.onPause();
}
@Override
protected void onRestart() {
Log.d(TAG, "onRestart()");
super.onRestart();
}
@Override
protected void onResume() {
Log.d(TAG, "onResume()");
super.onResume();
}
@Override
protected void onStart() {
Log.d(TAG, "onStart()");
super.onStart();
}
@Override
protected void onStop() {
Log.d(TAG, "onStop()");
super.onStop();
}
public void onBatteryOk()
{
Log.d(TAG, "onBatteryOk");
}
public void onBatteryLow()
{
Log.d(TAG, "onBatteryLow()");
}
public void onBatteryChanged()
{
Log.d(TAG, "onBatteryChanged");
}
public void onShutdown()
{
Log.d(TAG, "onShutdown");
}
private Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
switch (msg.what)
{
case msgBatteryLow:
onBatteryLow();
break;
case msgBatteryChanged:
onBatteryChanged();
break;
case msgShutdown:
onShutdown();
break;
case msgBatteryOK:
onBatteryOk();
break;
default:
super.handleMessage(msg);
break;
}
super.handleMessage(msg);
}
};
public void startSystemMonitor()
{
registerReceiver(lowBatteryReceiver, lowBatteryFilter);
registerReceiver(batteryChangedReceiver, batteryChangedFilter);
registerReceiver(shutdownReceiver, shutdownFilter);
}
public void stopSystemMonitor()
{
unregisterReceiver(lowBatteryReceiver);
unregisterReceiver(batteryChangedReceiver);
unregisterReceiver(shutdownReceiver);
}
private final BroadcastReceiver lowBatteryReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "lowBatteryReceiver:onReceive()" + ", action:" + intent.getAction());
if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW))
{
mHandler.sendEmptyMessage(msgBatteryLow);
} else if (intent.getAction().equals(Intent.ACTION_BATTERY_OKAY)){
mHandler.sendEmptyMessage(msgBatteryOK);
} else {
assert true;
}
}
};
private static final IntentFilter lowBatteryFilter = new IntentFilter();
static {
lowBatteryFilter.addAction(Intent.ACTION_BATTERY_LOW);
lowBatteryFilter.addAction(Intent.ACTION_BATTERY_OKAY);
}
private final BroadcastReceiver batteryChangedReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED))
{
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
Log.d(TAG, "ACTION_BATTERY_CHANGED: " + level + ", Extra:" + BatteryManager.EXTRA_SCALE);
Message msg = new Message();
msg.what = msgBatteryChanged;
msg.arg1 = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
msg.arg2 = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
mHandler.sendMessage(msg);
} else {
assert true;
}
}
};
private static final IntentFilter batteryChangedFilter = new IntentFilter();
static {
batteryChangedFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
}
private final BroadcastReceiver shutdownReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SHUTDOWN))
{
Log.d(TAG, "ACTION_SHUTDOWN");
mHandler.sendEmptyMessage(msgShutdown);
} else {
assert true;
}
}
};
private static final IntentFilter shutdownFilter = new IntentFilter();
static {
shutdownFilter.addAction(Intent.ACTION_SHUTDOWN);
}
}

0 件のコメント:
コメントを投稿