(转)Android:AppWidget,PendingIntent,RemoteViews用法

来源:互联网 发布:format在vb是什么意思 编辑:程序博客网 时间:2024/06/04 23:33

什么是AppWidget?AppWidget就是我们平常在桌面上见到的那种一个个的小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作。本篇打算从以下几个点来介绍AppWidget:

      1.如何创建一个简单的AppWidget

      2.如何使得AppWidget与客户端程序交互

下面我们来创建一个简单的AppWidget

1、定义AppWidgetProviderInfor:在res/xml文件夹中定义一个名为 :example_appwidget_info.xml,这个名字随便取。它是提供AppWidget元数据;设置在桌面上显示的大小 

example_appwidget_info.xml

[html] view plaincopy
  1. <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:minWidth="294dp"  
  3.     android:minHeight="72dp"  
  4.     android:updatePeriodMillis="86400000"  
  5.     android:initialLayout="@layout/example_appwidget">  
  6.     <!-- initiallayout设置引用 的布局文件 -->  
  7.  </appwidget-provider>  

2、为App Widget指定样式和布局;在桌面上显示的内容,布局,就像main.xml布局一样,做为example_appwidget_info.xml的initialLayout参数的值,用这个布局文件来初始化example_appwidget_info.xml。

[javascript] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8.     android:id="@+id/widgetTextId"  
  9.     android:layout_width="fill_parent"   
  10.     android:layout_height="wrap_content"   
  11.     android:text="firstWidgetText"  
  12.     android:background="#000000"  
  13.     />  
  14. </LinearLayout>  

3、实现继承AppWidgetProvider这个类;

这个类有五个方法:都需要继承:(下面按照当第一次加载Widget到删除的时候,这些方法运行的顺序)

1、onReceive(Context context, Intent intent)   Implements onReceive(Context, Intent) to dispatch calls to the various other methods on AppWidgetProvider.

2、onEnabled(Context context)  Called in response to the ACTION_APPWIDGET_ENABLED broadcast when the a AppWidget for this provider is instantiated. Override this method to implement your own AppWidget functionality.

3、onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)  Called in response to the ACTION_APPWIDGET_UPDATE broadcast when this AppWidget provider is being asked to provide RemoteViews for a set of AppWidgets. Override this method to implement your own AppWidget functionality.

4、onDeleted(Context context, int[] appWidgetIds)  Called in response to the ACTION_APPWIDGET_DELETED broadcast when one or more AppWidget instances have been deleted. Override this method to implement your own AppWidget functionality.

5、onDisabled(Context context)  Called in response to the ACTION_APPWIDGET_DISABLED broadcast, which is sent when the last AppWidget instance for this provider is deleted. Override this method to implement your own AppWidget functionality.

基中onReceive负责进行接受广播,控制运行哪一个函数,每一个操作都会首先运行这个方法,再调用其它的方法。所以在Widget一次加载到删除过程中,onReceive会执行4次;

如下图:注意message


下面看代码:ExampleAppWidgetProvider.java

[java] view plaincopy
  1. public class ExampleAppWidgetProvider extends AppWidgetProvider {  
  2.     @Override  
  3.     public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
  4.             int[] appWidgetIds) {  
  5.         System.out.println("onupdate");  
  6.         super.onUpdate(context, appWidgetManager, appWidgetIds);  
  7.     }  
  8.   
  9.     @Override  
  10.     public void onDeleted(Context context, int[] appWidgetIds) {  
  11.         System.out.println("onDeleted");  
  12.         super.onDeleted(context, appWidgetIds);  
  13.     }  
  14.   
  15.     @Override  
  16.     public void onDisabled(Context context) {  
  17.         System.out.println("onDisabled");  
  18.         super.onDisabled(context);  
  19.     }  
  20.   
  21.     @Override  
  22.     public void onEnabled(Context context) {  
  23.         System.out.println("onEnabled");  
  24.         super.onEnabled(context);  
  25.     }  
  26. }  
在这个实例中,因为与Activity脱离关系,所以Activity不用更改,只是在应用系统中注册了一个与这个应用程序相关的AppWidget而已:结果:


下面再来看看如何在AppWidget中添加按钮,添加监听事件。

1、在example_appwidget_info.xml文件里添加Button迫使

2、添加TargetActivity

只是用来响应点击事件,在此例中没有实际意义

[java] view plaincopy
  1. public class TargetActivity extends Activity {  
  2.     @Override  
  3.     protected void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6.     }  
  7. }  

3、在AndroidManifest.xml文件注册TargetActivity

4、重写ExampleAppWidgetProvider类的onUpdate方法,在第一次创建WidGet的时候,向按钮添加监听。并用PendingIntent,和RemoteView两个类,对事件进行处理;

[java] view plaincopy
  1. public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
  2.             int[] appWidgetIds) {  
  3.         System.out.println("onupdated");  
  4.   
  5.         for (int i = 0; i <appWidgetIds.length; i++) {  
  6.             System.out.println(appWidgetIds[i]);  
  7.             //创建一个Intent对象  
  8.             Intent intent = new Intent(context,TargetActivity.class);  
  9.             //创建一个PendingIntent(有四种方法获取)  
  10.             PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  11.             RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.example_appwidget);  
  12.             //为按钮绑定事件处理器  
  13.             //第一个参数用来指定被绑定处理器的控件的ID  
  14.             //第二个参数用来指定当事件发生时,哪个PendingIntent将会被执行  
  15.             remoteViews.setOnClickPendingIntent(R.id.widgetButton, pendingIntent);  
  16.             //更新AppWidget  
  17.             //第一个参数用于指定被更新AppWidget的ID  
  18.             appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);  
  19.         }  
  20.         super.onUpdate(context, appWidgetManager, appWidgetIds);  
  21.     }  

Called in response to the ACTION_APPWIDGET_DELETED broadcast when one or more AppWidget instances have been deleted. Override this method to implement your own AppWidget functionality.


在实际应用在AppWidget更多的是利用广播机制Action进行处理的;下面我们来看看如何利用广播机制,单击改变AppWidget的内容;在上例 的基础上进行扩展:

1、AppWidget的布局文件:widget01.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <Button android:id="@+id/widgetButton"  
  8.     android:layout_width="fill_parent"  
  9.     android:layout_height="wrap_content"  
  10.     android:text="@string/widget_button"/>  
  11.       
  12. <TextView android:id="@+id/test_text"  
  13.     android:layout_width="fill_parent"  
  14.     android:layout_height="wrap_content"  
  15.     android:text="@string/test_text"  
  16.     android:gravity="center"  
  17.     android:textColor="#fff"/>  
  18. </LinearLayout>  
其中的Button控件是测试按钮,TextView用来反应单击Button之后显示的内容变化;(这是给Button添加监听器,再利用Action广播。收onRecerve接收,做出动作)

2、修改AndroidManifest.xml

在Reservi里添加action,注册事件

[html] view plaincopy
  1. <receiver android:name="ExampleAppWidgetProvider"><!--如果action匹配成功,就在此类中进行处理-->  
  2.     <intent-filter>  
  3.         <!--利用广播机制接收,onUpdate会接收广播。查看源码可收得知  Called in response to the ACTION_APPWIDGET_UPDATE   
  4.             broadcast when this AppWidget provider is being asked to provide RemoteViews   
  5.             for a set of AppWidgets. Override this method to implement your own AppWidget   
  6.             functionality. 这个也必须要,不然onRecerve不会调用 。-->  
  7.         <!--这是自定义的Action事件--><action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>  
  8.         <action android:name="learn.test.UPDATE_APP_WIDGET"/>  
  9.     </intent-filter>  
  10.     <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_test" />  
  11. </receiver>  
3、修改ExampleAppWidgetProvider.java代码文件,如下:

[java] view plaincopy
  1. public class ExampleAppWidgetProvider extends AppWidgetProvider {  
  2.     //定义一个常量字符串,该常量用于命名Action  
  3.     private static final String UPDATE_ACTION = "learn.test.UPDATE_APP_WIDGET";  
  4.       
  5.     @Override  
  6.     public void onDeleted(Context context, int[] appWidgetIds) {  
  7.         // TODO Auto-generated method stub  
  8. System.out.println("onDeleted");  
  9.         super.onDeleted(context, appWidgetIds);  
  10.     }  
  11.   
  12.     @Override  
  13.     public void onDisabled(Context context) {  
  14.         // TODO Auto-generated method stub  
  15. System.out.println("onDisabled");  
  16.         super.onDisabled(context);  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onEnabled(Context context) {  
  21.         // TODO Auto-generated method stub  
  22. System.out.println("onEnabled");  
  23.         super.onEnabled(context);  
  24.     }  
  25.   
  26.     @Override  
  27.     public void onReceive(Context context, Intent intent) {  
  28.         // TODO Auto-generated method stub  
  29. System.out.println("onReceive");  
  30.   
  31.         String action = intent.getAction();  
  32.         if (UPDATE_ACTION.equals(action)) {  
  33.             RemoteViews remoteViews = new RemoteViews(context.getPackageName(),  
  34.                     R.layout.widget01);  
  35.             remoteViews.setTextViewText(R.id.test_text, "this is OnReceive");  
  36.             //getInstance(Context context)  Get the AppWidgetManager instance to use for the supplied Context object.静态方法。  
  37.             AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);  
  38.               
  39.             ComponentName componentName = new ComponentName(context,ExampleAppWidgetProvider.class);  
  40.             appWidgetManager.updateAppWidget(componentName, remoteViews);  
  41.         } else {  
  42.             super.onReceive(context, intent);这里一定要添加,eles部分,不然,onReceive不会去调用其它的方法。但是如果把这条语句放在外面,就会每次运行onUpdate,onDeleted等方法,就会运行两次,因为UPDATE_ACTION.equals(action)配置成功会运行一次,uper.onReceive(context, intent)配置成功又会运行一次,后都是系统自定义的。  
  43.         }  
  44.     }  
  45.   
  46.     @Override  
  47.     public void onUpdate(Context context, AppWidgetManager appWidgetManager,  
  48.             int[] appWidgetIds) {  
  49.         // TODO Auto-generated method stub  
  50. System.out.println("onUpdated");  
  51.   
  52. //创建一个Intent对象  
  53.         Intent intent = new Intent();  
  54.         //为Intent对象设置Action  
  55.         intent.setAction(UPDATE_ACTION);  
  56.         //使用getBroadcast方法,得到一个PendingIntent对象,当该对象执行时,会发送一个广播  
  57.         PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,  
  58.                 intent, 0);  
  59.         RemoteViews remoteViews = new RemoteViews(context.getPackageName(),  
  60.                 R.layout.widget01);  
  61.           
  62.         remoteViews.setOnClickPendingIntent(R.id.widgetButton, pendingIntent);  
  63.         appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);  
  64.         super.onUpdate(context, appWidgetManager, appWidgetIds);  
  65.     }  
  66.       
  67. }  

转自:http://blog.csdn.net/huangbiao86/article/details/6680632