アプリを作る際、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 件のコメント:
コメントを投稿