電量+簡訊 Widget

1 篇文章 / 0 new
author
電量+簡訊 Widget
設計目的當一個裝置電源過低時則發送簡訊至手機, 使用的主要技術 Widget, Service, SMS
►主程式
// 電量 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();
        }
    }
}
►batterywidget.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"
/>
►Widget.xml Widget的外觀佈局
<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>
►AndroidManifest.xml 主要參數
<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);
Free Web Hosting