設計目的當一個裝置電源過低時則發送簡訊至手機, 使用的主要技術 Widget, Service, SMS
►主程式
►主程式
►batterywidget.xml 告訴系統該Widget要使用你一個佈局及尺寸// 電量 Widget public class BatteryWidgetProvider extends AppWidgetProvider { private static float batteryLevel = 0; // 電量更新 serivce public static class BatteryUpdateService extends Service { private static final String ACTION_UPDATE = "shioulo.battery.free.action.UPDATE"; private final static IntentFilter intentFilter; static {//設定要接收的訊息 intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);//系統訊息 intentFilter.addAction(ACTION_UPDATE);//WidgetProvider訊息 } //接收系統電量改變通知 private final BroadcastReceiver batteryChangedReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action == null) return; // if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {//電量有變化 int rawLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1); if (scale > 0) { batteryLevel = rawLevel * 100 / scale; } else { batteryLevel = rawLevel; } intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1); intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1); updateBattery(context); } else if (action.equals(ACTION_UPDATE)) {//畫面更新 updateBattery(context); } } }; // public IBinder onBind(Intent intent) { return null; } //登錄訊息接收 public void onCreate() { super.onCreate(); registerReceiver(batteryChangedReceiver, intentFilter); } //取消訊息接收 public void onDestroy() { super.onDestroy(); unregisterReceiver(batteryChangedReceiver); } //service 啟動 public void onStart(Intent intent, int startId) { if (intent != null && intent.getAction() != null) { if (intent.getAction().equals(ACTION_UPDATE)) { updateBattery(this); } } } } /** * 更新 widget 顯示資料 * @param context 用來取得相關資源 */ private static void updateBattery(Context context) { //取得 Views RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); int btVlaue = (int) batteryLevel; remoteViews.setTextColor(R.id.battery, Color.WHITE); remoteViews.setTextViewText(R.id.battery, String.valueOf(btVlaue)+"%"); //更新 Widget 顯示 ComponentName tweetWidget = new ComponentName(context, BatteryWidgetProvider.class); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); appWidgetManager.updateAppWidget(tweetWidget, remoteViews); //發送簡訊 sendSMS(context, btVlaue); } /** * {@inheritDoc} */ public void onDisabled(Context context) { super.onDisabled(context); context.stopService(new Intent(context, BatteryUpdateService.class)); } /** * {@inheritDoc} */ public void onEnabled(Context context) { super.onEnabled(context); context.startService(new Intent(BatteryUpdateService.ACTION_UPDATE)); } /** * {@inheritDoc} */ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); context.startService(new Intent(BatteryUpdateService.ACTION_UPDATE)); } //發送簡訊 //http://stackoverflow.com/questions/8998655/unable-to-send-sms-using-smsmanager-in-android //http://www.pocketdigi.com/20110715/395.html private static void sendSMS(Context context, int btVlaue) { if (btVlaue<=0) return;//初始啟動值為 0 try { SharedPreferences pp = context.getSharedPreferences("param", 0); int send = pp.getInt("SEND", 0); if ((btVlaue>70)&&(send>0)) {//電源恢復, 取消發送紀錄 70 pp.edit().putInt("SEND", 0).commit(); return; } if ((btVlaue>50)||(send>0)) return;//40 //發送通知 pp.edit().putInt("SEND", 1).commit(); send = pp.getInt("SEND", 0); if (send>0) {//確定寫入成功才發送,避免一直不斷發送 SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage("對方的手機號碼", null, "手機電源過低:"+String.valueOf(btVlaue)+"%", null, null); Toast.makeText(context.getApplicationContext(), "簡訊傳送!", Toast.LENGTH_LONG).show(); } } catch(Exception e) { Toast.makeText(context.getApplicationContext(), "簡訊傳送失敗!", Toast.LENGTH_LONG).show(); } } }
►Widget.xml Widget的外觀佈局<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget" android:minWidth="60dip" android:minHeight="60dip" android:updatePeriodMillis="0" />
►AndroidManifest.xml 主要參數<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/widgetLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <TextView android:id="@+id/battery" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@android:color/black" android:contentDescription="@string/AppName" android:textSize="50dp" /> </LinearLayout>
► 電池相關資訊<application android:allowBackup="false" android:icon="@drawable/ic_launcher" android:label="電池簡訊" > <receiver android:name="shioulo.battery.free.BatteryWidgetProvider" android:label="@string/AppName" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/batterywidget" /> </receiver> <service android:name="shioulo.battery.free.BatteryWidgetProvider$BatteryUpdateService" android:exported="false" > <intent-filter> <action android:name="shioulo.battery.free.action.UPDATE" /> </intent-filter> </service> </application>
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0); icon_small = intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL, 0); plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); present = intent.getExtras().getBoolean(BatteryManager.EXTRA_PRESENT); scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0); technology = intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY); temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0); voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);