2011年9月17日土曜日

Android アプリの終了処理:Low BatteryとShutdown(1)



アプリを作る際、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の作り方など、こちらを参考にさせてもらっています。

  1. package test.sample.battery;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. import android.content.BroadcastReceiver;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.content.IntentFilter;  
  10. import android.os.BatteryManager;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.util.Log;  
  14.   
  15.   
  16. public class BatteryTestActivity extends Activity {  
  17.  private static final String TAG = "BatteryTest";  
  18.    
  19.  private final static int msgBatteryLow = 1;  
  20.  private final static int msgShutdown = 2;  
  21.  private final static int msgBatteryChanged = 3;  
  22.  private final static int msgBatteryOK = 4;  
  23.    
  24.  @Override  
  25.     public void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.main);  
  28.         startSystemMonitor();  
  29.     }  
  30.   
  31.  @Override  
  32.  protected void onDestroy() {  
  33.   Log.d(TAG, "onDestroy()");  
  34.   super.onDestroy();  
  35.   stopSystemMonitor();  
  36.  }  
  37.   
  38.  @Override  
  39.  protected void onPause() {  
  40.   Log.d(TAG, "onPause()");  
  41.   super.onPause();  
  42.  }  
  43.   
  44.  @Override  
  45.  protected void onRestart() {  
  46.   Log.d(TAG, "onRestart()");  
  47.   super.onRestart();  
  48.  }  
  49.   
  50.  @Override  
  51.  protected void onResume() {  
  52.   Log.d(TAG, "onResume()");  
  53.   super.onResume();  
  54.  }  
  55.   
  56.  @Override  
  57.  protected void onStart() {  
  58.   Log.d(TAG, "onStart()");  
  59.   super.onStart();  
  60.  }  
  61.   
  62.   
  63.   
  64.  @Override  
  65.  protected void onStop() {  
  66.   Log.d(TAG, "onStop()");  
  67.   super.onStop();  
  68.  }  
  69.   
  70.   
  71.  public void onBatteryOk()  
  72.  {  
  73.   Log.d(TAG, "onBatteryOk");  
  74.  }  
  75.  public void onBatteryLow()  
  76.  {  
  77.   Log.d(TAG, "onBatteryLow()");  
  78.  }  
  79.    
  80.  public void onBatteryChanged()  
  81.  {  
  82.   Log.d(TAG, "onBatteryChanged");  
  83.  }  
  84.   
  85.  public void onShutdown()  
  86.  {  
  87.   Log.d(TAG, "onShutdown");  
  88.  }  
  89.   
  90.  private Handler mHandler = new Handler()  
  91.  {  
  92.   
  93.   @Override  
  94.   public void handleMessage(Message msg) {  
  95.    switch (msg.what)  
  96.    {  
  97.    case msgBatteryLow:  
  98.     onBatteryLow();  
  99.     break;  
  100.    case msgBatteryChanged:  
  101.     onBatteryChanged();  
  102.     break;  
  103.    case msgShutdown:  
  104.     onShutdown();  
  105.     break;  
  106.    case msgBatteryOK:  
  107.     onBatteryOk();  
  108.     break;  
  109.       
  110.    default:  
  111.     super.handleMessage(msg);  
  112.     break;  
  113.    }  
  114.    super.handleMessage(msg);  
  115.   }  
  116.     
  117.  };  
  118.    
  119.    
  120.  public void startSystemMonitor()  
  121.  {  
  122.   registerReceiver(lowBatteryReceiver, lowBatteryFilter);  
  123.   registerReceiver(batteryChangedReceiver, batteryChangedFilter);  
  124.   registerReceiver(shutdownReceiver, shutdownFilter);  
  125.  }  
  126.    
  127.  public void stopSystemMonitor()  
  128.  {  
  129.   unregisterReceiver(lowBatteryReceiver);  
  130.   unregisterReceiver(batteryChangedReceiver);  
  131.   unregisterReceiver(shutdownReceiver);  
  132.  }  
  133.    
  134.  private final BroadcastReceiver lowBatteryReceiver = new BroadcastReceiver()  
  135.  {  
  136.   
  137.   @Override  
  138.   public void onReceive(Context context, Intent intent) {  
  139.    Log.d(TAG, "lowBatteryReceiver:onReceive()" + ", action:" + intent.getAction());  
  140.   
  141.    if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW))  
  142.    {  
  143.     mHandler.sendEmptyMessage(msgBatteryLow);  
  144.    } else if (intent.getAction().equals(Intent.ACTION_BATTERY_OKAY)){  
  145.     mHandler.sendEmptyMessage(msgBatteryOK);  
  146.    } else {  
  147.     assert true;  
  148.    }  
  149.      
  150.   }  
  151.     
  152.  };  
  153.   
  154.  private static final IntentFilter lowBatteryFilter = new IntentFilter();  
  155.     static {  
  156.      lowBatteryFilter.addAction(Intent.ACTION_BATTERY_LOW);  
  157.      lowBatteryFilter.addAction(Intent.ACTION_BATTERY_OKAY);  
  158.     }  
  159.    
  160.  private final BroadcastReceiver batteryChangedReceiver = new BroadcastReceiver()  
  161.  {  
  162.   
  163.   @Override  
  164.   public void onReceive(Context context, Intent intent) {  
  165.    if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED))  
  166.    {  
  167.     int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);  
  168.   
  169.     Log.d(TAG, "ACTION_BATTERY_CHANGED: " + level + ", Extra:" + BatteryManager.EXTRA_SCALE);  
  170.   
  171.     Message msg = new Message();  
  172.     msg.what = msgBatteryChanged;  
  173.     msg.arg1 = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);  
  174.     msg.arg2 = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);  
  175.       
  176.     mHandler.sendMessage(msg);  
  177.   
  178.    } else {  
  179.     assert true;  
  180.    }  
  181.      
  182.   }  
  183.     
  184.  };  
  185.   
  186.  private static final IntentFilter batteryChangedFilter = new IntentFilter();  
  187.     static {  
  188.      batteryChangedFilter.addAction(Intent.ACTION_BATTERY_CHANGED);  
  189.     }  
  190.   
  191.  private final BroadcastReceiver shutdownReceiver = new BroadcastReceiver()  
  192.  {  
  193.   
  194.   @Override  
  195.   public void onReceive(Context context, Intent intent) {  
  196.    if (intent.getAction().equals(Intent.ACTION_SHUTDOWN))  
  197.    {  
  198.     Log.d(TAG, "ACTION_SHUTDOWN");  
  199.     mHandler.sendEmptyMessage(msgShutdown);  
  200.    } else {  
  201.     assert true;  
  202.    }  
  203.      
  204.   }  
  205.     
  206.  };  
  207.  private static final IntentFilter shutdownFilter = new IntentFilter();  
  208.     static {  
  209.      shutdownFilter.addAction(Intent.ACTION_SHUTDOWN);  
  210.     }  
  211.   
  212. }  

0 件のコメント:

コメントを投稿