androidの桌面小控制元件(1)—電池狀態顯示
桌面小控制元件的實現是基於Broadcast的形式實現的,因此,每一個桌面小控制元件都對應於一個BroadcastReceiver類。Android系統提供了一個AppWidgetProvider類(它就是BroadcastReceiver的子類),這個類很關鍵,你在寫桌面小控制元件時只需繼承這個類就行。繼承了AppWidgetProvider類之後,你可以根據自己的需要覆蓋它的不同的生命週期的方法,來達到自己的目的。AppWidgetProvider類的主要提供如下不同生命週期的方法:
void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) { }
// 這個方法字面意思是負責更新桌面小控制元件,但貌似只有在小控制元件被使用者放到桌面上時被呼叫了一次,讀者可以自己通過輸出Log來測試
// 實現桌面控制元件是通常都會考慮重寫該方法
void onDeleted(Context context, int[] appWidgetIds)
// 在小控制元件被刪除時呼叫該方法
void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) { }
// 這個方法字面意思是負責更新桌面小控制元件,但貌似只有在小控制元件被使用者放到桌面上時被呼叫了一次,讀者可以自己通過輸出Log來測試
// 實現桌面控制元件是通常都會考慮重寫該方法
void onDeleted(Context context, int[] appWidgetIds)
// 在小控制元件被刪除時呼叫該方法
一般來說,開發桌面小控制元件只需要定義一個AppWidgetProvider的子類,並重新寫它的pnUpdate方法即可。
2. 示例講解
先定義一個AppWidgetProvider子類。。public class AppWidet extends AppWidgetProvider { private static int currentBatteryLevel; private static int currentBatteryStatus; public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); // 啟動自動更新電池資訊的service context.startService(new Intent(context, updateService.class)); //為AppWidget設定點選事件的響應,啟動顯示電池資訊詳情的activity Intent startActivityIntent = new Intent(context,BatteryInfoActivity.class); PendingIntent Pintent = PendingIntent.getActivity(context, 0,startActivityIntent, 0); RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.other_layout); views.setOnClickPendingIntent(R.id.imageView, Pintent); appWidgetManager.updateAppWidget(appWidgetIds, views); } // 自動更新電池資訊的service ,通過AlarmManager 實現定時不間斷的傳送電池資訊 public static class updateService extends Service { // 定義機器人圖片 Bitmap bmp; @Override public IBinder onBind(Intent intent) { return null; } // 定義一個接受電池資訊的broadcastReceiver private BroadcastReceiver batteryReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 獲取當前電量 currentBatteryLevel = intent.getIntExtra("level", 0); // 獲取當前電池狀態 // 電池狀態,返回是一個數字 // BatteryManager.BATTERY_STATUS_CHARGING 表示是充電狀態 // BatteryManager.BATTERY_STATUS_DISCHARGING 放電中 // BatteryManager.BATTERY_STATUS_NOT_CHARGING 未充電 // BatteryManager.BATTERY_STATUS_FULL 電池滿 currentBatteryStatus = intent.getIntExtra("status", 0); } }; public void onStart(Intent intent, int startId) { super.onStart(intent, startId); // 註冊監聽電池資訊廣播 registerReceiver(batteryReceiver, new IntentFilter( Intent.ACTION_BATTERY_CHANGED)); // 定義一個AppWidgetManager物件 AppWidgetManager manager = AppWidgetManager.getInstance(this); // 定義一個RemoteViews,實現對AppWidget的控制 RemoteViews views = new RemoteViews(getPackageName(), R.layout.other_layout); // 當正在充電或充滿電時,顯示充電的圖片 if (currentBatteryStatus == 2 || currentBatteryStatus == 5) { ....... } else { // 未進行充電 ....... } // 設定AppWidget上顯示的圖片和文字的內容 views.setImageViewBitmap(R.id.imageView, bmp); views.setTextViewText(R.id.tv, currentBatteryLevel + "%"); // 將AppWidgetProvider子類例項包裝成ComponentName物件 ComponentName thisWidget = new ComponentName(this, AppWidet.class); // 使用AlarmManager實現每隔一秒傳送一次更新提示資訊,實現資訊實時動態變化 long now = System.currentTimeMillis(); long pause = 1000; Intent alarmIntent = new Intent(); alarmIntent = intent; PendingIntent pendingIntent = PendingIntent.getService(this, 0, alarmIntent, 0); // 定時傳送更新提示 AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarm.set(AlarmManager.RTC_WAKEUP, now + pause, pendingIntent); manager.updateAppWidget(thisWidget, views); } } }
然後是點選桌面外掛顯示介面。
public class BatteryInfoActivity extends Activity {
..........
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); // 設定activity無標題
setContentView(R.layout.main_layout); // 使用newlayout的佈局
tvBatteryStatus = (TextView) findViewById(R.id.tvBatteryStatus);
tvBatteryLevel = (TextView) findViewById(R.id.tvBatteryLevel);
tvBatteryHealth = (TextView) findViewById(R.id.tvBatteryHealth);
tvBatteryTemperature = (TextView) findViewById(R.id.tvBatteryTemperature);
tvBatteryVoltage = (TextView) findViewById(R.id.tvBatteryVoltage);
tvBatteryTechnology = (TextView) findViewById(R.id.tvBatteryTechnology);
flag = true; // 提示service的標誌位置為true
infoReceiver = new BroadcastReceiver() // 提示資訊接收器的定義
{
@Override
public void onReceive(Context context, Intent intent) {
setText(); //收到intent,就及時修改TextView資訊,使得Activity顯示時,電池資訊也能動態顯示
}
};
//註冊提示資訊的intentFilter
IntentFilter filter = new IntentFilter();
filter.addAction("com.wyl.example.broadcast");
registerReceiver(infoReceiver, filter);
// 啟動提示service
Intent startService = new Intent(this, updateService.class);
startService(startService);
}
//點選螢幕任意位置,關閉電池資訊Activity
public boolean onTouchEvent(MotionEvent event) {
this.finish();
return true;
}
@Override
protected void onDestroy() {
flag = false;
unregisterReceiver(infoReceiver);
super.onDestroy();
}
//及時動態修改Activity上文字資訊的函式
public static void setText() {
。。。。
}
/** 提示資訊變化的service,約每隔一秒,就傳送intent,
* 提醒activity更新電池資訊,主要為了檢測電池狀態的變化,
* 例如連上充電時,狀態會從“未在充電”變為“正在充電”
* 通過呼叫plugged方式,還能判斷是AC方式充電還是USB方式充電
*/
public static class updateService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
/** 定義得到電池資訊的BroadcastReceiver,提取出關鍵資訊,存入變數中 */
private BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
currentBatteryStatus = intent.getIntExtra("status", 0);
currentBatteryLevel = intent.getIntExtra("level", 0);
currentBatteryHealth = intent.getIntExtra("health", 0);
currentBatteryTemperature = intent
.getIntExtra("temperature", 0);
currentBatteryVoltage = intent.getIntExtra("voltage", 0);
currentBatteryTechnology = intent.getStringExtra("technology");
currentBatteryPlugged = intent.getIntExtra("plugged", 0);
}
};
public void onStart(Intent intent, int startId) {
registerReceiver(batteryReceiver, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
/** 啟動一個執行緒,約每隔一秒就傳送intent提醒Activity更新電池資訊 */
new Thread() {
public void run() {
while (flag) {
Intent sendInfoToActivity = new Intent();
sendInfoToActivity
.setAction("com.wyl.example.broadcast");
sendBroadcast(sendInfoToActivity);
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}.start();
super.onStart(intent, startId);
}
}
}