使用已知的AppWidgetProviderInfo创建窗口小部件
问题描述:
而不是向用户显示窗口小部件提供程序列表,我让他选择一个然后配置窗口小部件,我手动加载所有窗口小部件提供程序并让用户将这些窗口小部件拖放到我的应用程序中。 只要用户放弃这样一个图标,我想要创建和配置这个小部件。我该怎么做呢?使用已知的AppWidgetProviderInfo创建窗口小部件
代码注释
// 1) get a list of all app widget providers
List<AppWidgetProviderInfo> providers = mAppWidgetManager.getInstalledProviders();
// 2) Display the list to the user and let him select a widget provider => done via custom UI
// 3) handle the user selected widget and create it
// 3.1) create new widget id
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
// 3.2) configure widget
// ??? How do I do this now? appWidgetInfo.configure = null, so I can't use this as I normally would do it
// 4) Save the appWidgetId or delete it again depending on if the user finished the setup or cancelled it
普通方法(因为我的用例并不重要,但总体上描述了它是如何工作)
- 创建窗口小部件的ID,然后使用
AppWidgetManager.ACTION_APPWIDGET_PICK
意图让用户在选择后选择一个小部件 - ,将数据传递给
AppWidgetManager.ACTION_APPWIDGET_CONFIGURE
意图和使用intent.setComponent(appWidgetInfo.configure);
- 设置后,保存的小工具ID(或删除,如果用户取消设置)在我的自定义数据和使用id来显示和更新部件
- =>对于我而言,这是做工精细...
问题
如何获得有效的AppWidgetProviderInfo
与组态现场= NULL,这样我可以使用以下:
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
// appWidgetInfo.configure is null for appWidgetInfo received from mAppWidgetManager.getInstalledProviders()
// it is not if the appWidgetInfo is received via the AppWidgetManager.ACTION_APPWIDGET_PICK intent...
intent.setComponent(appWidgetInfo.configure);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
activity.startActivityForResult(intent, WIDGET_CONFIGURE_REQUEST_CODE);
或者还有其他方法吗?
我觉得我莫名其妙必须手动创建与AppWidgetProviderInfo
一个小部件,然后用reget的mAppWidgetManager.getAppWidgetInfo(appWidgetId);
信息,然后我将有一个充满configure
场,因为这似乎是,如果我使用AppWidgetManager.ACTION_APPWIDGET_PICK
意图发生,但我不知道我这样做手动...
答
我可以解决这个问题。 ACTION_APPWIDGET_PICK
意图将小部件绑定到id,因此必须在我的情况下手动完成:
private static void configureWidgetManually(AppCompatActivity activity, AppWidgetProviderInfo appWidgetInfo) {
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
boolean hasPermission = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidgetInfo.provider);
if (!hasPermission) {
// this if part is untested, I never get into this part, but from my understanding it should work like this...
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, appWidgetInfo.provider);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, appWidgetInfo.getProfile());
}
// Result of this can be handled the same way as the result of AppWidgetManager.ACTION_APPWIDGET_PICK, so we can even use the same request code...
activity.startActivityForResult(intent, WIDGET_SELECTOR_REQUEST_CODE);
} else {
// Widget is bound, we can continue as if we would have used the `AppWidgetManager.ACTION_APPWIDGET_PICK` intent
appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
configureWidget(activity, appWidgetId, appWidgetInfo);
}
}
private static void configureWidget(AppCompatActivity activity, int appWidgetId, AppWidgetProviderInfo appWidgetInfo) {
if (appWidgetInfo.configure != null) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setComponent(appWidgetInfo.configure);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
activity.startActivityForResult(intent, WIDGET_CONFIGURE_REQUEST_CODE);
} else {
// widget is configured, do whatever you want with the id...
}
}