Android - 将AppWidgets添加到活动中

时间:2012-04-03 18:56:26

标签: android widget

我最初的目标是将Google搜索小部件添加到活动的线性布局中。我需要包含它就像它出现并在Launcher中工作(这就是为什么我需要能够添加小部件)。


我想在我的活动中添加小部件,而不必启动小部件选择器活动。我试过了:  

1。直接指定一个整数id(我总是得到膨胀错误)

 

2。得到这样的id:

  ComponentName cn = new ComponentName(getBaseContext(), "com.android.quicksearchbox.SearchWidgetProvider");
  int[] ids = AppWidgetManager.getInstance(getApplicationContext()).getAppWidgetIds (cn);

(数组总是空的)

这些都不起作用。

在此之后我有了这个代码,使用ID(如果我从小部件选择器活动中获取ID,它就有效):

    AppWidgetProviderInfo withWidgetInfo = AppWidgetManager.getInstance(getApplicationContext()).getAppWidgetInfo(appWidgetId);
    AppWidgetHostView hostView = myWidgetHost.createView(getBaseContext(), appWidgetId, withWidgetInfo);
    hostView.setAppWidget(appWidgetId, withWidgetInfo);
    LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
    ll.addView(hostView);

我该怎么办?谢谢!

2 个答案:

答案 0 :(得分:18)

试试这个:

// APPWIDGET_HOST_ID is any number you like
appWidgetManager = AppWidgetManager.getInstance(this);
appWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID);
AppWidgetProviderInfo newAppWidgetProviderInfo = new AppWidgetProviderInfo();

// Get an id
int appWidgetId = appWidgetHost.allocateAppWidgetId();

// Get the list of installed widgets
List<AppWidgetProviderInfo> appWidgetInfos = new ArrayList<AppWidgetProviderInfo>();
appWidgetInfos = appWidgetManager.getInstalledProviders();

for(int j = 0; j < appWidgetInfos.size(); j++)
{
    if (appWidgetInfos.get(j).provider.getPackageName().equals("com.android.quicksearchbox") && appWidgetInfos.get(j).provider.getClassName().equals("com.android.quicksearchbox.SearchWidgetProvider"))
    {
        // Get the full info of the required widget
        newAppWidgetProviderInfo = appWidgetInfos.get(j);
        break;
    }
 }

// Create Widget
AppWidgetHostView hostView = appWidgetHost.createView(this, appWidgetId, newAppWidgetProviderInfo);
hostView.setAppWidget(appWidgetId, newAppWidgetProviderInfo);

// Add it to your layout
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
ll.addView(hostView);

修改

要绑定窗口小部件ID,即使窗口小部件更新并响应用户交互,请在此处参考解决方案:Widgets don't respond when re-added through code

答案 1 :(得分:6)

好吧,我设法制作了有效的代码(除了它应该并且不能轻易地工作 - 详细信息如下所示)。

应该起作用的代码是:

        //create ComponentName for accesing the widget provider
        ComponentName cn = new ComponentName("com.android.quicksearchbox", "com.android.quicksearchbox.SearchWidgetProvider");
        //ComponentName cn = new ComponentName("com.android.music", "com.android.music.MediaAppWidgetProvider");

        //get appWidgetManager instance
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getBaseContext());
        //get list of the providers - .getAppWidgetIds (cn) does seem to be unrelated to widget hosting and more related to widget development
        final List<AppWidgetProviderInfo> infos = appWidgetManager.getInstalledProviders();

        //get AppWidgetProviderInfo
        AppWidgetProviderInfo appWidgetInfo = null;
        //just in case you want to see all package and class names of installed widget providers, this code is useful
        for (final AppWidgetProviderInfo info : infos) {
            Log.v("AD3", info.provider.getPackageName() + " / "
                    + info.provider.getClassName());
        }
        //iterate through all infos, trying to find the desired one
        for (final AppWidgetProviderInfo info : infos) {
            if (info.provider.getClassName().equals(cn.getClassName()) && info.provider.getPackageName().equals(cn.getPackageName())) {
                //we found it
                appWidgetInfo = info;
                break;
            }
        }
        if (appWidgetInfo == null)
            return; //stop here

        //allocate the hosted widget id
        int appWidgetId = myWidgetHost.allocateAppWidgetId();

        //bind the id and the componentname - here's the problem!!!
        appWidgetManager.bindAppWidgetId(appWidgetId, cn); 

        //creat the host view
        AppWidgetHostView hostView = myWidgetHost.createView(getBaseContext(), appWidgetId, appWidgetInfo);
        //set the desired widget
        hostView.setAppWidget(appWidgetId, appWidgetInfo);

        //add the new host view to your activity's GUI
        LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
        ll.addView(hostView);

嗯,问题是“appWidgetManager.bindAppWidgetId(appWidgetId,cn);” - 这需要权限BIND_APPWIDGET - 在清单中。 - 即使我们放了,它仍然无法运作。我读过它可能会保留给系统应用程序

但是,即使在添加权限并将apk放入system / app文件夹后,它仍然无效(它不会使其成为系统应用程序)。

关于这个问题,我找到了这个答案here

  

这是故意不适用于应用程序。如果你想   添加小部件,您需要启动选择器UI供用户选择   然后将处理绑定的小部件。小部件可以暴露   所有类型的许多私人数据,所以允许一个不安全   应用程序在没有用户隐式的情况下任意绑定它们   批准(通过选择UI)。

     

Dianne ... Android框架工程师

然而,我不确定但是,如果我们可以用图像开发者的密钥签署apk,这可能意味着我们可以实现所需的功能?但是,这不是问题的主题。 但是,如果你碰巧能够向我解释如何有效地托管AppWidgets,那么我可以接受你的答案(市场上的发射器应用程序可以做到这一点,所以它必须是可能的)。