Android – добавление AppWidgets к активности

Моя первоначальная цель – добавить виджет Google Search в линейную компоновку активности. Мне нужно включить его так же, как он появляется, и работает в Launcher (вот почему мне нужно добавить виджет).


Я хотел бы добавить виджеты в свою деятельность, не имея необходимости запускать виджет. Я попытался:

1. непосредственно указать целочисленный id (я всегда получаю ошибки надувания)

2. Получить идентификатор:

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

(Массив всегда пуст)

Ни одна из этих работ не работает.

После этого у меня есть этот код, чтобы использовать идентификатор (он работает, если я получаю идентификатор от активности выбора виджета):

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

Как я должен это делать? Спасибо!

Solutions Collecting From Web of "Android – добавление AppWidgets к активности"

Попробуй это:

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

EDIT :

Чтобы связать идентификаторы виджетов, то есть обновлять виджеты и реагировать на взаимодействие с пользователем, см. Решение здесь: Виджеты не реагируют при повторном добавлении кода

Ну, мне удалось сделать код, который работает (за исключением того, что он должен и не может работать так легко – подробности приведены ниже).

Код, который должен работать:

  //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 он все равно не работает (это не делает его системным приложением).

Что касается этой проблемы, я нашел здесь этот ответ:

Это намеренно недоступно для приложений. Если вы хотите добавить виджет, вам нужно запустить пользовательский интерфейс выбора, чтобы пользователь мог выбрать виджет, который затем позаботится о привязке. Виджеты могут выставлять много частных данных всех типов, поэтому небезопасно разрешать приложению произвольно связываться с ними, если пользователь неявно одобряет (через пользовательский интерфейс выбора).

Dianne … Android framework engineer

Однако я не уверен, но, может быть, это означает, что мы могли бы достичь желаемой функциональности, если бы смогли подписать apk с ключом разработчика изображения? Однако это не относится к теме вопроса. Но если вам удастся объяснить мне, как эффективно размещать AppWidgets, пожалуйста, сделайте и ответьте на мой ответ (приложения для запуска на рынке могут это сделать, поэтому это должно быть возможно).