本文主要讲解如何发布App Widget。
要创建一个App Widget
1. AppWidgetProviderInfo, 描述app widget 的元数据,诸如App Widget的layout,更新频率和AppWidgetProvider class。在XML中定义。
2. AppWidgetProvider class的实现,定义基本的方法,允许你以编程的方式与AppWidget互动,基于广播事件。
3. View Layout,定义app widget 的初始布局。
<receiver android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/example_appwidget_info" />
</receiver>
APPWIDGET_UPDATE是必须申明的一条接收事件。
AppWidgetManager会自动发送所有其他的事件到AppWidgetProvider。
AppWiggetProviderInfo 定义了必要的信息,诸如:最小尺寸,初始布局资源,更新频率,可选的在创建AppWidget时要启动的配置Activitity。在xml中定义,如下
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="40dp" android:minHeight="40dp" android:updatePeriodMillis="86400000" android:previewImage="@drawable/preview" android:initialLayout="@layout/example_appwidget" android:configure="com.example.android.ExampleAppWidgetConfigure" android:resizeMode="horizontal|vertical" android:widgetCategory="home_screen|keyguard" android:initialKeyguardLayout="@layout/example_keyguard">
</appwidget-provider>
其中需要说明的是widgetCategory 指定了可显示的地方,从上段代码可看到该widget可显示在homescreen 与 keyguard
AppWidget的layout是基于 RemoteViews,所以它并不是支持所有类型的layout或者widget,详情可查看SDK。
地址如下:SDK/docs/guide/topics/appwidgets/index.html#CreatingLayout
AppWidgetProvider 继承BroadcastReceiver, 方便处理广播,只接受AppWidget发出的事件,注入AppWidget的updated, deleted, enabled, and disabled。
以下方法必须实现:
- onUpdate(), 该方法将根据xml定义的更新时间进行周期性调用,且该方法也会在用户添加widget时调用,因此可做一些 the essential setup, 诸如view的事件处理,启动临时服务等。
- onAppWidgetOptionsChanged(), 这是在 first placed and any time the widget is resized时调用,
- onDeleted(Context, int[]),an App Widget is deleted from App Widget Host.
- onEnabled(Context),an instance the App Widget is created for the first time,比如只需要打开一次的数据库,可在该处初始化。
- onDisabled(Context), clean up any work done in onEnabled(Context)
- onReceive(Context, Intent), called for every broadcast and before each of the above callback methods. 通常无需实现。
当不需要打开临时文件,数据库或者其他需要清理的资源时,只需要实现onUpdate()
示例就是一个按钮启动Activity:
public class ExampleAppWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
其中,onUpdate中有轮询appWidgetId,事实上,这是对于该Provider创建的所有appWidget的进行挨个更新。当然了,只有在同时更新的appWidget才会被轮训。
先到此,后续更新。