这是我们这个小项目的最后一篇了,大家一定是非常期待的,那么我们就来看看这最后一篇的内容吧。
注意: 因为这个AppWidgetProvider 是一个广播接收器BroadcastReceiver,不能保证你的进程在回调函数返回后仍然继续运行(参见应用程序基础>广播接收器的生命周期 Application Fundamentals > Broadcast Receiver Lifecycle以获取更多信息)。如果你的App Widget设置过程能持续几秒钟(也许当执行网页请求时)而且你要求你的进程继续,考虑在onUpdated()方法里启动一个服务Service 。从这个服务里,你可以执行自己的App Widget更新,而不必担心AppWidgetProvider 由于一个应用程序无响应错误Application Not Responding (ANR)而关闭。参见Wiktionary sample's AppWidgetProvider,这是个App Widget运行一个Service的例子。
同样参见ExampleAppWidgetProvider.java 例子类。
接收App Widget广播意图
AppWidgetProvider 只是一个简便类。如果你想直接接收App Widget 广播,你可以实现自己的BroadcastReceiver 或者重写 onReceive(Context, Intent) 回调函数。你需要注意的4个意图如下:
Java代码:
[java]
1. ACTION_APPWIDGET_UPDATE
2. ACTION_APPWIDGET_DELETED
3. ACTION_APPWIDGET_ENABLED
4. ACTION_APPWIDGET_DISABLED
创建一个App Widget 配置活动
如果你想让用户在添加一个新的App Widget时调整设置,你可以创建一个App Widget配置活动。这个活动将被App Widget宿主自动启动并允许用户在创建时配置可用的设置,比如App Widget颜色,尺寸,更新周期或者其它功能设置。
这个配置活动应该在Android清单文件中声明为一个通用活动。不过,它将被通过ACTION_APPWIDGET_CONFIGURE活动而被App Widget宿主启动,因此这个活动需要接受这个意图。比如:
Java代码:
[java]
1. < activity android:name=".ExampleAppWidgetConfigure">
2. < intent-filter>
3. < action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
4. < /intent-filter>
5. < /activity>
同样的,活动必须在AppWidgetProviderInfo XML 文件中声明,通过android:configure属性(参见上面的添加AppWidgetProviderInfo元数据Adding the AppWidgetProviderInfo Metadata)。比如,配置活动可以声明如下:
Java代码:
[java]
1. < appwidget-provider xmlns:android=http://schemas.android.com/apk/res/android
2. ...
3. android:configure="com.example.android.ExampleAppWidgetConfigure"
4. ... >
5. < /appwidget-provider>
注意这个活动是用全名声明的,因为它将从你的程序包外被引用。
这就是所有关于配置活动你一开始需要了解的。现在你需要一个真实的活动。这儿就有,不过,当你实现这个活动时记住两件重要的事情:
App Widget 宿主调用配置活动而且配置活动应该总是返回一个结果.这个结果应该包含这个通过启动该活动的意图传递的App Widget ID(以EXTRA_APPWIDGET_ID保存在意图的附加段Intent extras中)
当这个 App Widget 被创建时将不会调用onUpdate() 方法(当一个配置活动启动时,系统将不会发送ACTION_APPWIDGET_UPDATE广播).配置活动应该在 App Widget 第一次被创建时负责从AppWidgetManager请求一个更新.不过, onUpdate() 将在后续更新中被调用-只忽略第一次.
参见下面章节的代码片断,该示例说明了如何从配置中返回一个结果并更新这个App Widget.
从配置活动中更新一个App Widget
当一个App Widget使用一个配置活动,那么当配置结束时,就应该由这个活动来更新这个App Widget.你可以直接AppWidgetManager里请求一个更新来这么做.
下面是恰当的更新App Widget 以及关闭配置活动这个过程的一个概要描述:
1. 首先,从启动这个活动的意图中获取App Widget ID:
Java代码:
[java]
1. Intent intent = getIntent();
2. Bundle extras = intent.getExtras();
3.
4. if (extras != null) {
5. mAppWidgetId = extras.getInt(
6. AppWidgetManager.EXTRA_APPWIDGET_ID,
7. AppWidgetManager.INVALID_APPWIDGET_ID);
8. }
2. 实施你的App Widget 配置。
3. 当配置完成后,通过调用getInstance(Context)获取一个AppWidgetManager实例:
Java代码:
[java]
1. AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
2. AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
4. 以一个RemoteViews布局调用updateAppWidget(int, RemoteViews)更新App Widget:
Java代码:
[java]
1. RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
2. appWidgetManager.updateAppWidget(mAppWidgetId, views);
5. 最后,创建返回意图,设置活动结果,并结束这个活动:
Java代码:
[java]
1. Intent resultValue = new Intent();
2. resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
3. setResult(RESULT_OK, resultValue);
4. finish();
提示:当你的配置活动第一次打开时,设置活动结果为RESULT_CANCELED。这样,如果用户在结束之前从活动外返回,这个App Widget 宿主会接收到配置取消通知而不会添加这个App Widget。