2011-10-26

在 Android 註冊 Receiver 的兩種方法(外加讀取電力狀態、動態改變 Emulator 電力狀態與傳送 Notification )

靜態的 Manifest 或者動態的程式註冊。

先看程式註冊,重點在於 registerReceiver(...) 與 unregisterReceiver(...),記得要在 onResume(...) 裡註冊與在 onPause(...) 裡撤銷,否則會浪費資源。

public class ReceiverActivity extends Activity {

    private static String TAG = "ReceiverActivity";

    private BroadcastReceiver bcReceiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.bcReceiver = new BatteryChangedReceiver();
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter itf = new IntentFilter();
        itf.addAction(Intent.ACTION_BATTERY_CHANGED);
        this.registerReceiver(this.bcReceiver, itf);
    }

    @Override
    protected void onPause() {
        super.onPause();
        this.unregisterReceiver(this.bcReceiver);
    }

}
Receiver 程式:
public class BatteryChangedReceiver extends BroadcastReceiver {

 private static String TAG = "BatteryChangedReceiver";

 @Override
 public void onReceive(Context context, Intent intent) {
  Log.d(TAG, "The incoming action is " + intent.getAction());
  if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
   int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);
   int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
   int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
   String technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
   String statusStr = this.parseStatus(status);
   String pluggedStr = this.parsePlugged(plugged);
   StringBuilder msg = new StringBuilder();
   msg.append("電量 - " + statusStr + "\n");
   msg.append("電力 - " + level + "\n");
   msg.append("來源 - " + pluggedStr + "\n");
   msg.append("電池 - " + technology + "\n");
   Log.d(TAG, "Battery stats - " + msg);
   this.sendNotification(context, msg.toString());
  }
 }

 private String parseStatus(int status) {
  String statusStr;
  switch (status) {
  case BatteryManager.BATTERY_STATUS_CHARGING:
   statusStr = "充電中";
   break;
  case BatteryManager.BATTERY_STATUS_DISCHARGING:
   statusStr = "耗電中";
   break;
  case BatteryManager.BATTERY_STATUS_FULL:
   statusStr = "充飽了";
   break;
  case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
   statusStr = "沒電了";
   break;
  case BatteryManager.BATTERY_STATUS_UNKNOWN:
   statusStr = "不知道";
   break;
  default:
   statusStr = "";
  }
  return statusStr;
 }

 private String parsePlugged(int plugged) {
  String statusStr;
  switch (plugged) {
  case BatteryManager.BATTERY_PLUGGED_AC:
   statusStr = "AC";
   break;
  case BatteryManager.BATTERY_PLUGGED_USB:
   statusStr = "USB";
   break;
  default:
   statusStr = "";
  }
  return statusStr;
 }

 private void sendNotification(Context context, String msg) {
  NotificationManager nmgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
  Notification n = new Notification(R.drawable.icon, msg,
    System.currentTimeMillis());
  Intent it = new Intent();
  PendingIntent pi = PendingIntent.getActivity(context, 0, it, 0);
  n.setLatestEventInfo(context, "電力狀態", msg, pi);
  nmgr.notify(1, n);
 }
}
因為 Receiver 不能操作 UI,所以使用 Notification 送出訊息。

靜態的 Manifest 只要在 AndroidManifest.xml 加上以下的設定就可以了。
<receiver android:name="idv.neil.receiver.BatteryChangedReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BATTERY_CHANGED"/>
    </intent-filter>
</receiver>
但是目前測試結果無效,找不到原因。

在 Android Emulator 測試時,只有在程式剛啟動時會接收到一次 broadcast,之後就悄然無聲了。

在網路上找到一個可以動態修改 Android Emulator 電力狀態的方法:
telnet localhost 5554
help
power
power capacity 16
這樣就會發送 android.intent.action.BATTERY_CHANGED 的 Broadcast 了。

沒有留言:

張貼留言