appwidget的功能非常有限
如果你的widget里面有一个TextView的话,你甚至无法得到这个控件中的文字内容,不要想用getText()方法,因为appwidget只支持一种对其包含控件的访问方法:
RemoteViews rv = new RemoteViews(packageName, layoutId);
rv中包含一些设置属性的方法
比如:setTextViewText(viewId, text)等
但是不支持一切getxxx方法
因此,你只能将数据呈现到appwidget上面。但是,你或许会遇到这种情况:从一个activity或service中获取数据显示到appwidget,当用户进一步操作时(点击了appwidget上的一个按钮),appwidget将会启动另一个activity或者service,并将数据传输给它。例如:启动一个dialog对话框activity让用户输入搜索关键字,用户点击确定之后,关键字会出现在appwidget上,再点击appwidget上的搜索按键,appwidget会启动浏览器,跳转到搜索页面。
如果以上情况,开发者不可能从appwidget中获取到关键字,因此,比较好的解决方法是利用sharedPreference,将关键字存储进sharedPreference,无论是appwidget的UI显示,还是浏览器activity获取关键字的操作,全部变成读取sharedPreference数据。当然,也可以用其存储方式。
什么是appwidget? 即application widget。 应用程序控件,就是在桌面显示的控件。AppWidget就是我们平常在桌面上见到的那种一个个的小控件,利用这个小控件可以给用户提供一些方便快捷的操作。
创建一个简单的appwidget。
相关概念:
1、AppWidgetProviderInfo对象:它是一个xml文件,为appWidget提供元数据,包括布局,更新频率等数据。这个对象定义在xml中。
2、AppWidgetProvider: 定义了appwidget的基本生命周期函数。
代码:
1、在layout中新建一个appwidgetlayout.xml文件。
Java代码
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:id="@+id/textview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
只是一个textview。这个是应用程序在桌面的控件。
2、在res中新建一个xml包,在这个包中新建一个appwidget_info.xml文件。
Java代码
android:minWidth="294dp" android:minHeight="72dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/appwidgetlayout" /> 这个xml为appwidget提供元数据,这个是在桌面的布局,而这个layout(appwidgetlayout)为在appwidget中控件的布局。 3、在包下新建我们的provider,他继承了AppWidgetProvider,只需要对它的生命周期进行处理就行了。 Java代码 public class AppWidgetprovider extends AppWidgetProvider { @Override public void onDeleted(Context context, int[] appWidgetIds) { // TODO Auto-generated method stub System.out.println("onDeleted"); super.onDeleted(context, appWidgetIds); } @Override public void onDisabled(Context context) { // TODO Auto-generated method stub System.out.println("onDisable"); super.onDisabled(context); } @Override public void onEnabled(Context context) { // TODO Auto-generated method stub System.out.println("onEnable"); super.onEnabled(context); } @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub System.out.println("onreceive"); super.onReceive(context, intent); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // TODO Auto-generated method stub System.out.println("onUpdate"); super.onUpdate(context, appWidgetManager, appWidgetIds); } } 4、在AndroidManifest.xml中进行配置,由于这个appwidget使用的是广播机制,我们需要在AndroidManifest.xml中进行如下配置: Java代码 android:resource="@xml/appwidget_info" /> 通过过滤器截取APPWIDGET_UPDATE这个action,然后对provider进行资源配置,对应的刚刚那个xml中的文件。 android之appwidget(二)启动新activity appwidget的周期函数对应的事件: onUpdate:到达指定时间之后或者用户向桌面添加appwidget时候会调用这个方法。 onDelete:当appwidget被删除时,会调用这个方法。 onEnable:当一个appwidget第一次被创建,会调用这个方法。 onDisable:当最后一个appwidget实例被删除后,会调用这个方法。 onReveice:接受广播事件。 appwidget交互: 功能:创建一个appwidget(为一个button),点击后,启动一个activity。 1、appwidget与对应的activity不是同一个进程,appwidget是homescreen中的一个进程。所以,不能直接对某一个控件进行事件监听,而是通过RemoteViews进行处理,而且我们也不能直接用intent进行启动activity,用pendingintent。 2、pendingintent:顾名思义,是还未确定的Intent。可以看做是对intent的一个包装,目的是对RemoteViews进行设置。形象点讲就是进程A中的intent想要在进程B中执行,需要pendingintent进行包装,然后添加到进程B中,进程B中遇到某个事件,然后执行intent。 创建pendingintent有三个方法:getActivity(context,requestCode,intent,flags)。getService()。getBroadcast()。 3、RemoteViews:即远程的views。它的作用是它所表示的对象运行在另外的进程中。 代码: 1、appwidget.xml中(即桌面控件上加上一个Button)代码: Java代码 2、在provider中的onUpdate方法中进行处理: Java代码 for(int i= 0;i System.out.println(appWidgetIds[i]); //新intent Intent intent = new Intent(context,Appwidget2Activity.class); //创建一个pendingIntent。 PendingIntent pendingIntent = PendingIntent.getActivity( context, 0, intent, 0); //创建一个remoteViews。 RemoteViews remoteViews = new RemoteViews( context.getPackageName(), R.layout.appwidget); //绑定处理器,表示控件单击后,会启动pendingIntent。 remoteViews.setOnClickPendingIntent(R.id.button, pendingIntent); appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews); } 因为可能有多个appwidget,所以要遍历。创建一个intent,与要启动的activity关联起来,然后根据该intent创建一个pendingintent。然后根据appwidget.xml创建一个remoteViews,然后对该views中的一个控件进行pendingintent绑定。 android之appwidget(三)自定义action广播 根据一个action而启动一个广播,从而完成需要的操作。 首先appwidget根本是基于广播事件的,这个从需要在AndroidManifest.xml配置receiver可以看出,既然是这样,那么也可以自己定义我们自己的action以及在provider中的onReceive中进行处理。 其次,需要知道appwidgetprovider的运行机制就更容易理解了,当appwidget有事件时就会发送一个广播(一个intent对象)到appwidgetprovider,它首先会启动onReceive方法来接收action,然后根据action的值来决定调用onUpdate,onDelete,onDisable,onEnable中的一个方法,它的这些方法都与一个action对应。 下面的实例实现的是自己定义一个action,然后在appwidgetprovider中的onReceiver中截取,然后输出一句话。 代码如下: 1、首先在AndroidManifest.xml加入 Java代码 android:name="android.appwidget.action.APPWIDGET_UPDATE"/> android:resource="@xml/appwidget_info"> 增加了一个过滤器:action为"hanl.UPDATE_ACTION"。 2、在onUpdate函数内增加一个intent,为它设置action为hanl.UPDATE_ACTION,然后用pendingintent包装intent,然后进行事件绑定。这个在appwidget(一)有具体讲解。 Java代码 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // TODO Auto-generated method stub //新intent Intent intent = new Intent(); //设置action,这个UPDATE_ACTION在上面定义的为static final String UPDATE_ACTION=hanl.UPDATE_ACTION; intent.setAction(UPDATE_ACTION); //创建一个pendingIntent。 PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, intent, 0); //创建一个remoteViews。 RemoteViews remoteViews = new RemoteViews( context.getPackageName(), R.layout.appwidget); //绑定处理器,表示控件单击后,会启动pendingIntent。 remoteViews.setOnClickPendingIntent(R.id.button, pendingIntent); //更新 appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); super.onUpdate(context, appWidgetManager, appWidgetIds); } 3、然后在onReceive中进行拦截。 Java代码 @Override ublic void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String action = intent.getAction(); if(action.equals(UPDATE_ACTION)) System.out.println("onReceive-----"+action); super.onReceive(context, intent); android之appwidget(四)终 appwidget控件更新 RemoteViews:指的是appwidget中的所有的控件。 componentName:指的是appwidget整个这个对象。 由于appwidget与主进程不是同一个进程,所以不能像在主进程中那样的操作,先get一个控件,然后set一个控件。 目标:在appwidget中放入一个textview , 一个imageView,和一个button,我们点击这个button他的textview 和imageview都发生改变。 代码: 1、首先在appwidget.xml中放入控件: Java代码 android:id="@+id/textview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="测试" />