`
abc20899
  • 浏览: 934003 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

让自己的Android应用支持appwidget

阅读更多
经常看到一些教程教你如何写appwidget,但是,你知道你的appwidget是如何被添加到桌面上的吗?
          一般的,如果是做桌面的童鞋,基本上都会让自己的桌面支持appwidget。下面说说如何实现。
          首先是得定义一个承载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.} 

需要注意的几点:
1。 必须调用AppWidgetHost的startListening方法来监听appwidget的状态变化,否则添加上去的appwidget不会更新的。
2。 需要override一个onActivityResult方法,来接收添加appwidget和appwidget的配置activity的返回值。
3。 启动AppWidgetManager.ACTION_APPWIDGET_PICK这个Intent,必须要给列表中加上自己定义的一个选项,否则出错。如本例中是用的Search。
分享到:
评论

相关推荐

    android 桌面控件appwidget

    Android 桌面控件(AppWidget)是Android操作系统提供的一种独特功能,允许开发者创建可以在用户主屏幕上显示的小型应用程序组件。这些控件通常提供快速访问应用的核心功能或展示实时信息,如天气预报、日历事件或...

    android之appwidget(二)启动新activity

    在Android开发中,AppWidget是桌面小部件,它允许用户在主屏幕上与应用程序进行交互,而无需实际打开应用。在本篇博文中,我们将深入探讨如何在AppWidget中启动一个新的Activity,这通常是为了提供更丰富的用户体验...

    android 桌面组件 App widget的使用 AppWidgetProvider

    &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt; android:name="android.appwidget.provider" android:resource="@xml/app_widget_info" /&gt; ``` 其中,`&lt;meta-data&gt;` 标签引用了一个 ...

    Android高级应用源码-Android小部件AppWidget.zip

    9. **服务(Service)与AppWidget**: 在某些情况下,你可能需要使用服务来支持AppWidget的后台任务,例如定时更新。Service可以用来处理这些长时间运行的任务,同时保持小部件的更新。 10. **兼容性与版本差异**: ...

    android之appwidget

    **Android之AppWidget详解** AppWidget是Android操作系统提供的一种组件,允许开发者在用户主屏幕上创建小型应用程序,这些小部件...通过理解和熟练运用AppWidget,开发者可以构建出更加丰富和个性化的Android应用。

    Android -- AppWidget的开....zip

    在Android系统中,AppWidget是桌面小部件的实现方式,它允许开发者将应用程序的功能和信息直接集成到用户的主屏幕上,用户无需打开应用就能与之交互。AppWidget虽然看似简单,但其实涉及到了许多核心的Android组件和...

    安卓Widget小组件相关-Android小部件AppWidget.rar

    这个压缩包“Android小部件AppWidget.rar”似乎包含了一些关于创建和实现Android Widget小组件的资源,可能是源代码、文档或者示例项目。 在Android开发中,AppWidget是Widget小组件的主要实现类。它是由Android ...

    android app widget小部件

    在这个名为"AppWidget-master"的压缩包中,我们很可能是得到了一个示例项目,用于演示如何创建一个能够显示列表并支持刷新功能的Android App Widget。 首先,我们需要理解App Widget的基本架构。App Widget由XML...

    创建appWidget

    创建一个新的Android项目,确保目标API版本支持AppWidget功能。在`AndroidManifest.xml`中声明AppWidget提供者,例如: ```xml &lt;receiver android:name=".AppWidgetProvider"&gt; &lt;action android:name="android....

    AppWidget-master.zip

    通过深入学习和实践这个源码示例,你将能够掌握AppWidget的开发流程,为自己的Android应用添加更多元化的交互方式,提升用户体验。同时,这也为你进一步探索Android系统的广播机制、服务、ContentProvider等高级特性...

    android0中实现AppWidget集合.pdf

    在Android开发中,AppWidget是桌面小部件,可以让用户在主屏幕上放置应用程序的轻量级交互界面。在Android 4.0(API级别14)及以上版本,开发者可以创建AppWidget集合,展示一系列数据,例如列表或网格形式的条目。...

    安卓Widget小组件相关-androidWidget小组件开发.zip

    在Android平台上,Widget小组件是应用在主屏幕上提供快速访问或简单交互的一种方式。它们可以显示实时信息,比如天气、时钟或者新闻摘要,而无需用户打开完整的应用程序。本资料包"androidWidget小组件开发.zip"包含...

    Android UI组件AppWidget控件入门详解

    总的来说,Android AppWidget控件为开发者提供了扩展主屏幕功能的能力,通过简单的布局设计和广播机制,可以让用户在不打开应用程序的情况下与应用进行交互。这种交互方式不仅提升了用户体验,也使得应用程序更加...

    Android学习之AppWidget高级效果

    在Android开发中,AppWidget是桌面小部件,它允许用户在主屏幕上添加应用程序的功能,而无需实际打开应用程序。本文将深入探讨如何实现Android AppWidget的高级效果,以一个掷骰子的Widget为例。 首先,创建App...

    Android-Android桌面小部件widget日签Or日历可作为桌面日历

    在Android平台上,开发者可以利用Android桌面小部件(Widget)功能为用户提供便捷的桌面服务,比如...通过这样的项目实践,开发者能够提升自己的Android应用开发技能,并为用户提供富有创意和实用性的桌面体验。

    android 源码 android Widget开发案例 eclipse项目 直接导入

    总之,"android 源码 android Widget开发案例 eclipse项目 直接导入"为开发者提供了一个实践平台,通过它,开发者能够深入学习Widget的工作原理,提高Android应用的桌面体验设计能力,让手机界面更加个性化和实用。

    安卓Andriod源码——小部件AppWidget.zip

    在Android系统中,小部件(AppWidget)是用户可以在主屏幕上添加的应用程序组件,它们提供了一种无需打开应用即可与应用交互的方式。本资源“安卓Andriod源码——小部件AppWidget.zip”包含了关于创建和实现Android...

    android clockwidget

    AppWidget是Android系统中的一个特性,它让用户能够在主屏幕上放置应用程序的部分界面,提供快速访问和操作的功能。创建AppWidget需要实现一系列组件,如`AppWidgetProvider`(类似广播接收器的组件,响应特定事件)...

    Android开发入门之Appwidget用法分析

    在Android开发中,App Widget是一种轻量级的应用组件,它可以被添加到用户的桌面或其它支持App Widget的应用中,为用户提供快速访问或操作的功能。App Widget虽然不像完整的应用程序那样拥有丰富的交互,但它们可以...

Global site tag (gtag.js) - Google Analytics