綁定帳號登入

Android 台灣中文網

打印 上一主題 下一主題

[資料] 讓你的android應用桌面支持appwidget

[複製連結] 查看: 1606|回覆: 1|好評: 0
跳轉到指定樓層
樓主
暗桌之光 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2011-6-12 15:40

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
如果想讓你的應用支持appwidget,需要注意的幾點:
1.必須調用AppWidgetHost的startListening方法來監聽appwidget的狀態變化,否則添加上去的appwidget不會更新的。
2.需要override一個onActivityResult方法,來接收添加appwidget和appwidget的配置activity的返回值。
3.啟動AppWidgetManager.ACTION_APPWIDGET_PICK這個Intent,必須要給列表中加上自己定義的一個選項,否則出錯。如本例中是用的Search。

下面是完整的教程:

     首先是得定義一個承載appwidget的容器,系統的Launcher裡面 是用的CellLayout,實現的很不錯。我這裡就用一個簡單的自定義ViewGroup來搞定,它是以長按的坐標處為要添加的appwidget的起 始位置,簡單點說就是按到哪兒就添加到哪兒。
  1. package chroya.demo.widget;  
  2.   
  3. import android.content.Context;  
  4. import android.view.MotionEvent;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7.   
  8. /**
  9. * 承載widget的容器
  10. * @author chroya
  11. */  
  12. public class WidgetLayout extends ViewGroup {  
  13.     //存放touch的坐標  
  14.     private int[] cellInfo = new int[2];  
  15.     private OnLongClickListener mLongClickListener;   
  16.   
  17.     public WidgetLayout(Context context) {  
  18.         super(context);  
  19.         mLongClickListener = new OnLongClickListener() {  
  20.               
  21.             @Override  
  22.             public boolean onLongClick(View v) {  
  23.                   
  24.                 return false;  
  25.             }  
  26.         };  
  27.     }  
  28.       
  29.     public void addInScreen(View child, int width, int height) {  
  30.         LayoutParams lp = new LayoutParams(width, height);  
  31.         lp.x = cellInfo[0];  
  32.         lp.y = cellInfo[1];  
  33.         child.setOnLongClickListener(mLongClickListener);  
  34.         addView(child, lp);  
  35.     }  
  36.       
  37.     @Override  
  38.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  39.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  40.         LayoutParams lp;  
  41.         for(int index=0; index<getChildCount(); index++) {  
  42.             lp = (LayoutParams) getChildAt(index).getLayoutParams();  
  43.             getChildAt(index).measure(  
  44.                     MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.width),   
  45.                     MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, lp.height));  
  46.         }  
  47.     }  
  48.       
  49.     @Override  
  50.     public boolean dispatchTouchEvent(MotionEvent event) {  
  51.         cellInfo[0] = (int)event.getX();  
  52.         cellInfo[1] = (int)event.getY();  
  53.         return super.dispatchTouchEvent(event);  
  54.     }  
  55.   
  56.     @Override  
  57.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  58.         LayoutParams lp;  
  59.         for(int index=0; index<getChildCount(); index++) {  
  60.             lp = (LayoutParams) getChildAt(index).getLayoutParams();  
  61.             getChildAt(index).layout(lp.x, lp.y, lp.x+lp.width, lp.y+lp.height);  
  62.         }  
  63.     }  
  64.       
  65.     public static class LayoutParams extends ViewGroup.LayoutParams {  
  66.         int x;  
  67.         int y;  
  68.   
  69.         public LayoutParams(int width, int height) {  
  70.             super(width, height);  
  71.         }         
  72.     }  
  73. }
複製代碼
然後是重點了。還記得系統默認的桌面上,長按的時候出現的上下文菜單嗎?裡面 有好幾個選項,選擇widget之後,會彈出一個已經安裝的widget列表,選擇一個widget之後,就會添加到桌面。我們可以把第一步去掉,長按之 後,直接彈出已安裝的widget列表,這是一個activity,用AppWidgetManager.ACTION_APPWIDGET_PICK這 個Intent來啟動,必須帶上Extras,下面給出代碼中有,不詳敘。
  1. package chroya.demo.widget;  
  2.   
  3. import static android.util.Log.d;  
  4.   
  5. import java.util.ArrayList;  
  6.   
  7. import android.app.Activity;  
  8. import android.appwidget.AppWidgetHost;  
  9. import android.appwidget.AppWidgetManager;  
  10. import android.appwidget.AppWidgetProviderInfo;  
  11. import android.content.ComponentName;  
  12. import android.content.Intent;  
  13. import android.os.Bundle;  
  14. import android.view.View;  
  15. import android.view.View.OnLongClickListener;  
  16.   
  17. /**
  18. * 添加appwidget
  19. * @author chroya
  20. *
  21. */  
  22. public class Main extends Activity {  
  23.     private AppWidgetHost mAppWidgetHost;  
  24.     private AppWidgetManager mAppWidgetManager;  
  25.     private WidgetLayout layout;      
  26.       
  27.     private static final int REQUEST_PICK_APPWIDGET = 1;  
  28.     private static final int REQUEST_CREATE_APPWIDGET = 2;   
  29.     private static final int APPWIDGET_HOST_ID = 0x100;  
  30.     private static final String EXTRA_CUSTOM_WIDGET = "custom_widget";  
  31.       
  32.     @Override  
  33.     public void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.          
  36.         mAppWidgetManager = AppWidgetManager.getInstance(getApplicationContext());  
  37.         mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);  
  38.         //開始監聽widget的變化  
  39.         mAppWidgetHost.startListening();  
  40.          
  41.         layout = new WidgetLayout(this);  
  42.         layout.setOnLongClickListener(new OnLongClickListener() {  
  43.               
  44.             @Override  
  45.             public boolean onLongClick(View v) {  
  46.                   
  47.                 addWidget();  
  48.                 return false;  
  49.             }  
  50.         });  
  51.         setContentView(layout);  
  52.     }  
  53.       
  54.     @Override  
  55.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  56.         if (resultCode == RESULT_OK) {  
  57.             switch (requestCode) {  
  58.             case REQUEST_PICK_APPWIDGET:  
  59.                 addAppWidget(data);  
  60.                 break;  
  61.             case REQUEST_CREATE_APPWIDGET:  
  62.                 completeAddAppWidget(data);  
  63.                 break;  
  64.             }  
  65.         } else if (requestCode == REQUEST_PICK_APPWIDGET &&  
  66.                 resultCode == RESULT_CANCELED && data != null) {  
  67.             // Clean up the appWidgetId if we canceled  
  68.             int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);  
  69.             if (appWidgetId != -1) {  
  70.                 mAppWidgetHost.deleteAppWidgetId(appWidgetId);  
  71.             }  
  72.         }  
  73.     }  
  74.       
  75.     /**
  76.      * 選中了某個widget之後,根據是否有配置來決定直接添加還是彈出配置activity
  77.      * @param data
  78.      */  
  79.     private void addAppWidget(Intent data) {  
  80.         int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);  
  81.   
  82.         String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);  
  83.         d("addAppWidget", "data:"+ customWidget);  
  84.         if ("search_widget".equals(customWidget)) {  
  85.             //這裡直接將search_widget刪掉了  
  86.             mAppWidgetHost.deleteAppWidgetId(appWidgetId);  
  87.         } else {  
  88.             AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);  
  89.               
  90.             d("addAppWidget", "configure:"+ appWidget.configure);  
  91.             if (appWidget.configure != null) {  
  92.                 //有配置,彈出配置  
  93.                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);  
  94.                 intent.setComponent(appWidget.configure);  
  95.                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);  
  96.   
  97.                 startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);  
  98.             } else {  
  99.                 //沒有配置,直接添加  
  100.                 onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);  
  101.             }  
  102.         }  
  103.     }  
  104.       
  105.     /**
  106.      * 請求添加一個新的widget
  107.      */  
  108.     private void addWidget() {  
  109.         int appWidgetId = mAppWidgetHost.allocateAppWidgetId();  
  110.   
  111.         Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);  
  112.         pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);  
  113.         // add the search widget  
  114.         ArrayList<AppWidgetProviderInfo> customInfo =  
  115.                 new ArrayList<AppWidgetProviderInfo>();  
  116.         AppWidgetProviderInfo info = new AppWidgetProviderInfo();  
  117.         info.provider = new ComponentName(getPackageName(), "XXX.YYY");  
  118.         info.label = "Search";  
  119.         info.icon = R.drawable.ic_search_widget;  
  120.         customInfo.add(info);  
  121.         pickIntent.putParcelableArrayListExtra(  
  122.                 AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);  
  123.         ArrayList<Bundle> customExtras = new ArrayList<Bundle>();  
  124.         Bundle b = new Bundle();  
  125.         b.putString(EXTRA_CUSTOM_WIDGET, "search_widget");  
  126.         customExtras.add(b);  
  127.         pickIntent.putParcelableArrayListExtra(  
  128.                 AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);  
  129.         // start the pick activity  
  130.         startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);  
  131.     }      
  132.       
  133.     /**
  134.      * 添加widget
  135.      * @param data
  136.      */  
  137.     private void completeAddAppWidget(Intent data) {  
  138.         Bundle extras = data.getExtras();  
  139.         int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);  
  140.   
  141.         d("completeAddAppWidget", "dumping extras content="+extras.toString());  
  142.         d("completeAddAppWidget", "appWidgetId:"+ appWidgetId);  
  143.         AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);  
  144.          
  145.         View hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);  
  146.          
  147.         layout.addInScreen(hostView, appWidgetInfo.minWidth, appWidgetInfo.minHeight);         
  148.     }  
  149. }
複製代碼
運行效果如下:

「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)

評分

參與人數 1碎鑽 +10 收起 理由
y776 + 10 支持一下

查看全部評分

收藏收藏 分享分享 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
沙發
katrina | 收聽TA | 只看該作者
發表於 2011-8-3 13:36
謝謝分享
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則