AppWidget详解

来源:互联网 发布:公司邮箱的域名是什么 编辑:程序博客网 时间:2024/05/21 17:31
最近一直专研Android开发,希望得到大家的支持与帮助!这是最近学AppWidget做的笔记,希望帮到需要的人!让大家更快的进步!(一下只标注了核心代码,相信大家一定可以看懂的,若需要源码,可以回复说明,也希望大家顶顶贴!至于奖品吧。。。。当然期待哦!)
一、核心功能介绍(一)appwidget介绍:
我们的appwidget与我们对应的activity不是同一个进程,appwidget是homescreen中的一个进程。所以,我们不能直接对某一个控件进行事件监听,而是通过RemoteViews进行处理,而且我们也不能直接用intent进行启动activity,用pendingintent。
(二)pendingintent介绍(如同一个锦囊,用来包装intent对象):
顾名思义,是还未确定的Intent。可以看做是对intent的一个包装,目的是对RemoteViews进行设置。形象点讲就是我们进程A中的intent想要在进程B中执行,需要pendingintent进行包装,然后添加到进程B中,进程B中遇到某个事件,然后执行intent。
1.在创建PendingIntent对象之前要先创建intent对象:
Intent intent = newIntent(context,SecondActivity.class);
2.创建PendingIntent的方法(有三种)
1)启动一个activity
PndingIntentpendingIntent=PendingIntent.getActivity(context,
requestCode, intent,flags);
2)发送一个广播
.getBroadcast(context,requestCode, intent, flags);
3)发送一个服务
.getService(context,requestCode, intent, flags);
(三)RemoteViews:
即远程的views。他的作用是他所表示的对象运行在另外的进程中。
RemoteViews的作用:
1.RemoteViews对象表示了一系列的view对象
2.RemoteViews所表示的对象运行在另外的进程当中
二、开发流程:
* 1、在src文件夹下写一个类继承自AppWidgetProvider
* 2、在res/xml文件夹下新建appwidgetprovderinfo.xml
* 3AndroidManifest.xml注册Receiver
* 4AppWidgetManger:负责管理 AppWidget,向 AppwidgetProvider发送通知。
* 5RemoteViews:一个可以在其他应用进程中运行的类,向 AppWidgetProvider发送通知。
(一)、继承AppWidgetProvider类,并重载下列方法:
onUpdateonReceive方法尤为重要):
onUpdate:到达指定时间之后或者用户向桌面添加appwidget时候会调用这个方法。
onDelete:当appwidget被删除时,会调用这个方法。
Enable:当一个appwidget第一次被创建,会调用这个方法。
nDisable:当最后一个appwidget实例被删除后,会调用这个方法。
onReveice:接受广播事件。
生命周期为:
当第一个widget被创建出来时,执行顺序是:
onreceive
onEnabled
onreceive
onUpdate

当第二个相同的widget被创建出来时,执行顺序是:
onreceive
onUpdate

当第三个相同的widget被创建出来时,执行顺序是:
onreceive
onUpdate

删除一个widget时,执行顺序为:
onreceive
onDeleted

删除最后一个widget时,执行顺序为:
onreceive
onDeleted
onreceive
onDisabled

应考虑用户可以在桌面添加多个相同的App Widget,因此系统调用我们重载的方法时,很多时候都是传给我们一个id数组。
onUpdate是非常重要的一个方法。当用户在桌面添加一个App Widget时,或者用户定义的时钟updatePeriodMillis响应时,此方法都会被调用。但是如果用户定义了configurationActivity时,在用户添加小控件时,onUpdate不会被调用。
   @Override
publicvoid onUpdate(Contextcontext, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
      //TODO Auto-generatedmethod stub
      super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
(二)、在res/xml文件夹下定appwidgetproviderinfo.xml
在res文件夹下创建名为xml的文件夹,然后添加一个xml文件,Tag为appwidget-provider,
1、屏幕一般被分为,4x4单元,因此我们定义的miniHeightminiWidth不要超过4x4单元的大小,每一单元大小为72x72dp, Google提供的基本原则是用你想占用的单元格数量乘以74,再减去2
2initialLayout用来声明Layout文件,该xml文件就在layout文件夹下!
3updatePeriodMills来定义更新AppWidget的时钟,当不需要更新时设置为0
代码如下:
//用来更新App Widget的时钟,当不需要更新时设置为0
定义一个App Widget,我们也需要定义它的Layout文件。在App Widget中,不是所有的Android控件都能放入App WidgetLayout中去的,现阶段只有下面一些Layout和控件才能放入App Widget中。
还有在程序中要控制App Widget的控件都通过RemoteViews来控制。
布局类:
LinearLayout FrameLayoutRelativeLayout
控件类:
AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar
TextView,ViewFlipper,ListView,GridView,StackView,AdapterViewFlipper
如果上述以外的控件或者Layout类被放入App WidgetLayout文件中的话,App Widget将不能在桌面显示。
(三)、在AndroidManifest.xml中进行配置
前面已经讲过,所有的AppWidgetProvider实际上都是BroadcastReceiver,因此在Manifest里面申明时使用receiver标签。meta-data标签的名字固定为"android.appwidget.provider"resource用来声明AppWidgetProviderInfoxmlintent-filter里面添“android.appwidget.action.
APPWIDGET_UPDATE”,当我们定义的时钟android:updatePeriodMillis响应时,会广播APPWIDGET_UPDATE,此时我们的onUpdate会被调用。
代码如下:
<receiver android:name="com.example.mywidget.MainActivity">
   <intent-filter>
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
   
         <meta-data
               android:name="android.appwidget.provider"
               android:resource="@xml/mywidget"/>
三、AppWidget 框架的主要类介绍
1)AppWidgetManger
    * bindAppWidgetId(int appWidgetId,ComponentName provider)
      
通过给定的ComponentName绑定appWidgetId
    * getAppWidgetIds(ComponentNameprovider)
      
通过给定的ComponentName获取AppWidgetId
    * getAppWidgetInfo(intappWidgetId)
      
通过AppWidgetId获取 AppWidget信息
    * getInstalledProviders()
      
返回一个List的信息
    * getInstance(Context context)
      
获取 AppWidgetManger实例使用的上下文对象
    * updateAppWidget(int[]appWidgetIds, RemoteViews views)
      
通过appWidgetId对传进来的 RemoteView进行修改,并重新刷新AppWidget组件
    * updateAppWidget(ComponentNameprovider, RemoteViews views)
通过ComponentName对传进来的 RemoeteView 进行修改,并重新刷新AppWidget组件
    * updateAppWidget(int appWidgetId,RemoteViews views)
      
通过appWidgetId对传进来的 RemoteView进行修改,并重新刷新AppWidget组件
四、在onUpdate方法中启动另一个activity
目标:创建一个appwidget(为一个button),点击后,启动一个activity。
onUpdate中写入代码:
for(int i= 0;i
               <action android:name="mars.appwidget03.UPDATE_APP_WIDGET"/>
//定义一个常量字符串,该常量用于命名Action
privatestaticfinal StringUPDATE_ACTION ="mars.appwidget03.UPDATE_APP_WIDGET";
onReceive方法中:
@Override
   publicvoid onReceive(Context context, Intent intent) {
      super.onReceive(context, intent);
       Stringaction = intent.getAction();
      if (UPDATE_ACTION.equals(action)) {
           System.out.println("onReceive--->" + UPDATE_ACTION);
       }
    }
onUpdate方法中:
   @Override
   publicvoid onUpdate(Context context, AppWidgetManagerappWidgetManager, int[] appWidgetIds) {
      //创建一个Intent对象
       Intent intent =new Intent();
      //Intent对象设置Action
       intent.setAction(UPDATE_ACTION);
//使用getBroadcast方法,得到一个PendingIntent对象,当该对象执行时,会发送一个广播
PendingIntentpendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews remoteViews =newRemoteViews(context.getPackageName(),
R.layout.example_appwidget);
remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
    }
六、使用RemoteViews对象跟新AppWidget当中的控件状态
注:由于AppWidget和主程序不在同一个进程当中,不能用普通的方法进行操作
1、在RemoteViews类当中有一系列的方法可以更新控件;
2、在使用RemoteViews更新控件状态之后,需要使用AppWManager通知AppWidget进行更新。
3、需要创建两个对象:AppWidgetManager(负责管理AppWidget,AppwidgetProvider发送通知)ComponentName对象
AndroidManifest.xml中的receiver中添加:
<intent-filter>
               <action android:name="mars.appwidget03.UPDATE_APP_WIDGET"/>
</intent-filter>
onReceive方法中:
@Override
   publicvoid onReceive(Context context, Intent intent) {
       String action = intent.getAction();
      if (UPDATE_ACTION.equals(action)) {
RemoteViews remoteViews=new RemoteViews(context.getPackageName(),
R.layout.example_appwidget);
remoteViews.setImageViewResource(R.id.imageId, R.drawable.ku);
      remoteViews.setTextViewText(R.id.widgetTextId,"test");
//创建一个AppWidgetManager对象
AppWidgetManager appWidgetManager =AppWidgetManager.getInstance(context);
//创建一个ComponentName对象
ComponentName componentName =new ComponentName(context,
ExampleAppWidgetProvider.class);
    appWidgetManager.updateAppWidget(componentName, remoteViews);
     }else {
           super.onReceive(context, intent);
       }
    }
onUpdate方法中:
   @Override
publicvoid onUpdate(Context context, AppWidgetManagerappWidgetManager,
int[] appWidgetIds) {
       Intent intent =new Intent();
       intent.setAction(UPDATE_ACTION);
PendingIntent pendingIntent= PendingIntent.getBroadcast(context, -1,
intent, 0);
RemoteViews remoteViews =newRemoteViews(context.getPackageName(),
R.layout.example_appwidget);
remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
    }


APKBUS原创,转出请注明出处http://www.apkbus.com/forum.php及作者dreamyounger!


1.png

0 0
原创粉丝点击