App Widget (二) 广播

来源:互联网 发布:域名dns检测 编辑:程序博客网 时间:2024/04/20 08:12

1} 接收来自AppWidget的广播
1) 在AndroidManifest.xml 中为AppWidgetProvider注册新的 intent-filter;
    要想接收一个广播,必须有一个intent-filter; 这个intent-filter 决定了哪些 消息(即 intent) 能被我们的 AppWidget 接收.
  从本质上来讲 AppWidgetProvider 就是一个 BroadcastReceiver.

<receiver android:name="ExampleAppWidgetProvider"><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><intent-filter><action android:name="mars.appwidget03.UPDATE_APP_WIDGET"/></intent-filter><meta-data android:name="android.appwidget.provider"android:resource="@xml/example_appwidget_info" /></receiver>
 在这里添加了一个Android系统自带的ACTION,以及自己定义的一个ACTION。 也就是说当 Intent 包含"android.appwidget.action.APPWIDGET_UPDATE" 或者"mars.appwidget03.UPDATE_APP_WIDGET"   ACTION时,就能够被 "ExampleAppWidgetProvider" 接收。
2) 使用getBroadcast() 方法创建一个PendingIntent  
     发送一个广播消息。
3) 为 App Widget 中的控件注册处理器
4) 在onReceive方法中接收广播信息
   AppWidgetProvider的运行机制:



Intent传递进来的消息由 onReceive来接收,onReceive 根据 Intent 里面的 ACTION决定调用哪个生命周期函数。
5) 代码
ExampleAppWidgetProvider.java

public class ExampleAppWidgetProvider extends AppWidgetProvider {//定义一个常量字符串,该常量用于命名Actionprivate static final String UPDATE_ACTION = "mars.appwidget03.UPDATE_APP_WIDGET";@Overridepublic void onDeleted(Context context, int[] appWidgetIds) {// TODO Auto-generated method stubsuper.onDeleted(context, appWidgetIds);}@Overridepublic void onDisabled(Context context) {// TODO Auto-generated method stubsuper.onDisabled(context);}@Overridepublic void onEnabled(Context context) {// TODO Auto-generated method stubsuper.onEnabled(context);}@Overridepublic void onReceive(Context context, Intent intent) {super.onReceive(context, intent);String action = intent.getAction();if (UPDATE_ACTION.equals(action)) {System.out.println("onReceive--->" + UPDATE_ACTION);}}@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {//创建一个Intent对象Intent intent = new Intent();//为Intent对象设置Actionintent.setAction(UPDATE_ACTION);//使用getBroadcast方法,得到一个PendingIntent对象,当该对象执行时,会发送一个广播PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,intent, 0);RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.example_appwidget);remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent);appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);}}
R.id.widgetButtonId  当按下这个Button时,就会引起 PendingIntent 中的 Intent 执行,它会发送一个广播。广播的ACTION为"mars.appwidget03.UPDATE_APP_WIDGET" 。这个ACTION和我们在 AndroidManifest.xml 中 <receiver> 的 <intent-filter> 一致,所以能通过过滤器。
这个广播  在同一个AppWidgetProvider 会得到接收,即在ExampleAppWidgetProvider的 onReceuve()方法中接收到。
String action = intent.getAction();
if (UPDATE_ACTION.equals(action))  { ... }

接收到之后,判断 ACTION. 是否相同 。就可以运行自己的内容了。

2} 更新AppWidget 中控件的状态
   本例要实现的效果,点一下App Widget中的Button,改变显示的图片。
1) 更改App Widget的布局文件example_appwidget.xml
     增加一个ImageView

<ImageViewandroid:id="@+id/imageId"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/xiao"/>

2)在 RemoteViews类 中有一系列的方法可以更新控件

3)在使用  RemoteViews  更新控件状态之后,要使用 appWidgetManager通知AppWidget进行更新。

4)代码

与上面的ExampleAppWidgetProvider.java只需更改onReceive的内容:
@Overridepublic void 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.getInstance(context);ComponentName componentName = new ComponentName(context,ExampleAppWidgetProvider.class);appWidgetManager.updateAppWidget(componentName, remoteViews);} else {super.onReceive(context, intent);}}

RemoteViews  代表了AppWidget 中所有的控件。 ComponentName 代表的是 AppWidget 对象。

怎么得到是哪个AppWidgetManager?  通过传递进来的 context 得到 :AppWidgetManager.getInstance(context);


0 0