【问题标题】:Binding Widgets in Custom Launcher在自定义启动器中绑定小部件
【发布时间】:2012-12-22 05:46:05
【问题描述】:

在我一直在使用的自定义启动器中将小部件添加到主屏幕时遇到一些问题。

我已经能够生成要使用 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 意图要求用户授予绑定应用程序的权限,这有点烦人。我的理解是,只有系统应用程序才能请求此权限,并且我在绑定小部件时运气不佳,而在应用程序运行时不请求此权限。另一方面,我知道还有许多其他启动器,它们都可以无缝添加小部件,因此必须有另一种方法。

任何建议将不胜感激!

干杯

【问题讨论】:

  • 您找到解决问题的方法了吗?

标签: android widget


【解决方案1】:

希望问题仍然悬而未决...

你在你的方法中做了太多的事情。在特定情况下,您会一个接一个地触发事件。我在 android 上工作的时间不长,所以我不能告诉你,这是否可以。

而且你总是在这里触发意图:

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 下。

【讨论】:

    【解决方案2】:

    这是我最终为我的应用找到的解决方案。

                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);
                    }
    
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 2018-09-28
      • 2013-06-03
      • 2021-08-14
      • 1970-01-01
      • 2015-07-27
      • 2011-03-30
      相关资源
      最近更新 更多