1. 功能:
創建Widget後,若爲飛行模式,點擊Widget,取消飛行模式,否則設置爲飛行模式。在變化過程中有動畫效果。
2. 實現思想:
對應main.xml佈局文件,Widget由三張圖片組成,pane上層左邊爲airplane,右邊爲switch點擊桌面widget時圖標的時候,左邊airplane四張圖標動態的在切換,直到設置爲飛行模式或者取消飛行模式狀態完成時,airplane切換停止,同時右邊switch圖片切換settrings_switch_on或者settrings_switch_off。
3. 程序中用到圖片資源文件如下:
settings_icon_airplane_01.png
settings_icon_airplane_02.png
settings_icon_airplane_03.png
settings_icon_airplane_04.png
settings_pane_off.png
settings_switch_off.png
settings_switch_on.png
widget_icon_airplane.png
//接受到發送到廣播時執行此方法
- code:
- 佈局文件main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <ImageView android:id="@+id/setting_pane"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/settings_pane_off"/>
- <ImageView android:id="@+id/setting_airplane"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:layout_marginLeft="6dip"
- android:src="@drawable/settings_icon_airplane_04"/>
- <ImageView android:id="@+id/setting_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/setting_airplane"
- android:layout_centerVertical="true"
- android:layout_marginLeft="4dip"
- android:src="@drawable/settings_switch_off"/>
- </RelativeLayout>
- 在res下新建xml文件夾,然後新建widget_provider.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
- android:minWidth="50dip" <-指定寬度度->
- android:minHeight="50dip" <-指定高度->
- android:initialLayout="@layout/main"/>
- 新建AirplaneModeEnabler類
- public class AirplaneModeEnabler{
- //此方法判斷是否爲飛行模式
- public static boolean isAirplaneModeOn(Context context){
- return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,0)!=0;
- }
- //此方法設置或取消飛行模式,enabling參數爲true,則設爲飛行模式,否則取消飛行模式
- public static void setAirplaneModeOn(Context context,boolean enabling){
- Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, enabling?1:0);
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", enabling);
- context.sendBroadcast(intent);
- }
- }
- 建MyWidget 類,繼承AppWidgetProvider,此類則widget第一次創建時執行oupdate方法,
- 即是廣播接受者,也是廣播發送者
- public class MyWidget extends AppWidgetProvider {
- private Context mContext = null;
- public RemoteViews remoteViews = new RemoteViews("com.archermind.widget", R.layout.main);
- public final static String SET_AIRPLANE_ACTION = "com.archermind.set_airplane_mode";
- private static final int START_ANIMATION = 0; //開始動畫
- private static final int END_ANIMATION = 1; //結束動畫
- private static Boolean mRunAnimation = false;
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //接受到消息後開始動畫效果,即連續切換4張圖片
- if (msg.what == START_ANIMATION) {
- Log.i("state", "START_ANIMATION: mRunAnimation = " + mRunAnimation);
- if (!mRunAnimation) {
- return;
- }
- //更新widget背景圖片
- remoteViews.setImageViewResource(R.id.setting_airplane, mDrawable[msg.arg1]);
- AppWidgetManager appWidgetManger = AppWidgetManager
- .getInstance(mContext);
- int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(
- mContext, MyWidget.class));
- for (int id: appIds) {
- appWidgetManger.updateAppWidget(id, remoteViews);
- }
- // send message for next frame
- Message message = mHandler.obtainMessage(START_ANIMATION);
- message.arg1 = (msg.arg1 + 1) % 4;
- mHandler.sendMessageDelayed(message, 200);
- } else if (msg.what == END_ANIMATION) { //結束動畫,
- Log.i("state", "END_ANIMATION: mRunAnimation = " + mRunAnimation);
- AppWidgetManager appWidgetManger = AppWidgetManager
- .getInstance(mContext);
- int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(
- mContext, MyWidget.class));
- for (int id: appIds) {
- updateAppWidget(mContext, appWidgetManger, id);
- }
- }
- Log.i("hThreadId",Long.toString(Thread.currentThread().getId()));
- }
- };
- private int[] mDrawable = {
- R.drawable.settings_icon_airplane_01,
- R.drawable.settings_icon_airplane_02,
- R.drawable.settings_icon_airplane_03,
- R.drawable.settings_icon_airplane_04
- };
- @Override
- public void onDeleted(Context context, int[] appWidgetIds) {
- super.onDeleted(context, appWidgetIds);
- Log.i("method", "onDeleted()");
- }
- @Override
- public void onDisabled(Context context) {
- super.onDisabled(context);
- Log.i("method", "onDisabled()");
- }
- @Override
- public void onEnabled(Context context) {
- super.onEnabled(context);
- Log.i("method", "onEnabled()");
- //創建widgt時,調用此方法,註冊電話監聽器
- TelephonyManager telephonyManager=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- telephonyManager.listen( mPhoneStateListener,PhoneStateListener.LISTEN_SERVICE_STATE);
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.i("method", "onReceive()");
- super.onReceive(context, intent);
- Log.i("action",intent.getAction());
- if(mContext ==null){
- mContext = context;
- }
- if(intent.getAction().equals(SET_AIRPLANE_ACTION)){
- boolean airplaneMode = AirplaneModeEnabler.isAirplaneModeOn(context);
- if(airplaneMode){
- AirplaneModeEnabler.setAirplaneModeOn(context, !airplaneMode);
- }else{
- AirplaneModeEnabler.setAirplaneModeOn(context, !airplaneMode);
- }
- Log.e("state", "onReceive: mRunAnimation = true");
- mRunAnimation = true;
- Message msg = mHandler.obtainMessage(START_ANIMATION);
- msg.arg1 = 0;
- mHandler.sendMessage(msg);
- }
- }
- @Override
- public void onUpdate(Context context, AppWidgetManager appWidgetManager,
- int[] appWidgetIds) {
- super.onUpdate(context, appWidgetManager, appWidgetIds);
- Log.i("method", "onUpdate()");
- if(mContext==null){
- mContext = context;
- }
- //創建RemoteViews,並調用updateAppWidget更新背景圖片
- remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
- int n = appWidgetIds.length;
- for (int i = 0; i < n; i++) {
- int appWidgetId = appWidgetIds[i];
- updateAppWidget(context, appWidgetManager, appWidgetId);
- }
- Log.i("length of appIds", ""+appWidgetIds.length);
- }
- //判斷當前是否爲飛行模式,並設置不同到背景圖片
- public void updateAppWidget(Context context,
- AppWidgetManager appWidgeManger, int appWidgetId) {
- boolean airplaneMode = AirplaneModeEnabler.isAirplaneModeOn(context);
- if(airplaneMode){
- remoteViews.setImageViewResource(R.id.setting_airplane,R.drawable.settings_icon_airplane_04);
- remoteViews.setImageViewResource(R.id.setting_switch,R.drawable.settings_switch_on);
- }else{
- remoteViews.setImageViewResource(R.id.setting_airplane,R.drawable.settings_icon_airplane_04);
- remoteViews.setImageViewResource(R.id.setting_switch,R.drawable.settings_switch_off);
- }
- //單機widget時發送廣播
- Intent intentClick = new Intent(SET_AIRPLANE_ACTION);
- PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
- intentClick, 0);
- remoteViews.setOnClickPendingIntent(R.id.setting_pane, pendingIntent);
- appWidgeManger.updateAppWidget(appWidgetId, remoteViews);
- }
- //電話監聽器,用來監聽是否爲飛行模式
- PhoneStateListener mPhoneStateListener = new PhoneStateListener(){
- @Override
- public void onServiceStateChanged(ServiceState serviceState) {
- super.onServiceStateChanged(serviceState);
- Log.i("phThreadId",Long.toString(Thread.currentThread().getId()));
- switch(serviceState.getState()){
- case ServiceState.STATE_IN_SERVICE:
- Log.i("state", "STATE_IN_SERVICE mRunAnimation = false");
- mRunAnimation = false;
- mHandler.sendMessage(Message.obtain(mHandler, END_ANIMATION));
- break;
- case ServiceState.STATE_POWER_OFF:
- Log.i("state", "STATE_POWER_OFF mRunAnimation = false");
- mRunAnimation = false;
- mHandler.sendMessage(Message.obtain(mHandler, END_ANIMATION));
- break;
- case ServiceState.STATE_OUT_OF_SERVICE:
- Log.i("state", "STATE_OUT_OF_SERVICE");
- break;
- case ServiceState.STATE_EMERGENCY_ONLY:
- Log.i("state", "STATE_EMERGENCY_ONLY");
- break;
- }
- }
- };
- }
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.archermind.widget"
- android:versionCode="1"
- android:versionName="1.0">
- <application android:icon="@drawable/widget_icon_airplane" android:label="@string/app_name">
- <receiver android:name=".MyWidget"
- android:label="@string/app_name" android:icon="@drawable/widget_icon_airplane">
- <intent-filter>
- <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
- <action android:name="com.archermind.set_airplane_mode" />
- </intent-filter>
- <meta-data android:name="android.appwidget.provider"
- android:resource="@xml/widget_provider"/>
- </receiver>
- </application>
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- </manifest>