android
中桌面插件主要依赖于AppWidget
框架。涉及类:
AppWidgetProvider
:BroadcastRecevier子类,用于接收更新,删除通知AppWidgetProvderInfo
:AppWidget相关信息(大小,更新频率等),xml形式AppWidgetManger
:AppWidget管理类,用于向provider发送消息RemoteViews
:可以在其他进程中运行的类,用于向provider发送通知。RemoteViewsService
: 是一个远程的服务适配器 可以请求RemoteViews,管理RemoteViews的服务.RemoteViewsFactory
: 提供了RemoteViewsFactory用于填充远程集合视图。AndroidManifest
xml
文件widget
布局Layout xml
文件AppWidgetProvider
,实现相关逻辑AndroidManifest.xml:
<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>
AppWidgetProvider
其本质是一个BroadcastReceiver
,其中,APPWIDGET_UPDATE
是必须的,用于接收broadcast
。
meta-data
声明了AppWidgetProviderInfo
对应的资源xml
的位置,其中包括Widget
的 xml
布局文件、刷新频率、最小宽高
res/xml/example_appwidget_info
<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">
appwidget-provider>
ExampleAppWidgetProvider:
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; iint 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);
}
}
}
<activity android:name=".ExampleAppWidgetConfigure">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
intent-filter>
activity>
添加widget
时弹出的activity
,需要添加android.appwidget.action.APPWIDGET_CONFIGURE
过滤器。
注意事项:
EXTRA_APPWIDGET_ID
的 result。Configuration Activity
后 onUpdate() 在 Widget 添加时不会被调用,Activity 需要调用 AppWidgetManager.updateAppWidget()
完成 Widget 更新。Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.example_appwidget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
上面的方式提供的方式是针对单个widget,如果我们的widget中包含ListView
,Gridview
等集合视图的时候.我们就需要借助一个类RemoteViewsService
,继承RemoteViewsService
并复写onGetViewFactory
返回RemoteViewsFactory
public class StackWidgetRemoteViewsService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {}
}
参考:
App Widgets
Android 开发之 App Widget 详解