我最初的目标是将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);
我该怎么办?谢谢!
答案 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,那么我可以接受你的答案(市场上的发射器应用程序可以做到这一点,所以它必须是可能的)。