绑定自定义启动器中的小部件

3

我在自定义启动器中添加小组件时遇到了一些问题。

我已经能够通过AppWidgetManager生成要添加的小组件列表,并开发了将小组件添加到我的主屏幕的工作流程。 代码不完全如下所示,但类似于以下内容:

AppWidgetHost widget_host = new AppWidgetHost(this, 1);
AppWidgetManager widget_manager = AppWidgetManager.getInstance(this);

int widget_id = widget_host.allocateAppWidgetId(); 
AppWidgetProviderInfo widget_provider = ... //from an array;

Intent bindIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget_id);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, widget_provider.provider);
startActivityForResult(bindIntent, REQUEST_BIND_APPWIDGET);

if (widget_provider.configure != null) {
    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
    intent.setComponent(widget_provider.configure);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget_id);
    startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
} else {
    createWidget(widget_id);
}

我随后有一个onActivityResult方法,如果需要,则会导致小部件配置,createWidget方法使用AppWidgetHost的createView方法。
这个工作流程可以运行,但ACTION_APPWIDGET_BIND意图会要求用户允许绑定应用程序,这有点烦人。我的理解是只有系统应用程序才能请求此权限,并且在应用程序运行时无法绑定小部件而不请求此权限。另一方面,我知道有许多其他启动器可用,它们都可以无缝添加小部件,因此必须有另一种方法来解决这个问题。
任何建议都将不胜感激!
干杯

你是否找到了解决问题的方法? - M_K
2个回答

3
这是我最终为我的应用程序找到的解决方案。
            AppWidgetManager manager = m.getAppWidgetManager();
            AppWidgetHost host = m.getWidgetHost();

            List<AppWidgetProviderInfo> widgetList = manager.getInstalledProviders();

            AppWidgetProviderInfo provider = null;
            for(AppWidgetProviderInfo info : widgetList){
                //To get the google search box
                if(info.provider.getClassName().equals("com.google.android.googlequicksearchbox.SearchWidgetProvider")){
                    provider = info;
                    break;
                }
            }
            if(provider != null){
                int id = host.allocateAppWidgetId();

                boolean success = false;
                success = manager.bindAppWidgetIdIfAllowed(id, provider.provider);
                if (success) {
                    AppWidgetHostView hostView = host.createView(getActivity(), id, provider);
                    AppWidgetProviderInfo appWidgetInfo = manager.getAppWidgetInfo(id);

                    LauncherAppWidgetInfo info = new LauncherAppWidgetInfo(id);
                    info.hostView = hostView;
                    info.hostView.setAppWidget(id, appWidgetInfo);
                    attachWidget(info);
                } else {
                    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,
                            provider.provider);
                    // TODO: we need to make sure that this accounts for the options
                    // bundle.
                    // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS,
                    // options);
                    m.startActivityForResult(intent, Main.REQUEST_BIND_APPWIDGET);
                }

            }
        }

3

希望问题仍然开放...

您在方法内部做了太多的事情。在特定情况下,您会短时间内连续触发事件。我在安卓上工作的时间不是很长,所以我无法告诉您这是否可以接受。

并且您总是在这里触发意图:

Intent bindIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget_id);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, widget_provider.provider);
startActivityForResult(bindIntent, REQUEST_BIND_APPWIDGET);

以上意图最有可能引起问题。您可以事先检查是否需要请求许可。您可以使用以下程序进行询问:

Boolean callProviderIntent = false;
if (checkCallProviderIntent)
{
    callProviderIntent = true;
    Method m = null;
    try
    {
        m = AppWidgetManager.class
            .getMethod("bindAppWidgetIdIfAllowed", new Class[]
            { Integer.TYPE, ComponentName.class });
    }
    catch (NoSuchMethodException e)
    {
    }
    if (m != null)
    {
        try
        {
            callProviderIntent = !(Boolean) m
             .invoke(mAppWidgetManager,
                     appWidgetId,
                     launcherAppWidgetInfo.provider);
        }
        catch (Exception e)
        {
        }
    }
}

这是虚拟代码。由于我使用的是Android 2.3,所以它使用了反射。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接