Intereting Posts
Возможно ли получить количество загрузок приложения из Google Play? Ошибка при работе с библиотекой Jackson после обфускации с использованием Proguard Есть ли способ добавить параметр запроса к каждому запросу с помощью Retrofit 2? Работа сNewIntent в фрагменте Эмулятор Visual studio (2015) для android не работает – XDE.exe – Код выхода 10 Как выполнить простую задачу async с помощью андроида Подобно Google Play INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES для установки adb Android: правильный способ использования onBackPressed () с помощью Toast Перейти на страницу в читателе epub (PageTurner) Пользовательский вид Android ActionBar не заполняет родительский Отображение диалогового окна Android Custom Alert после изменения версии сборки Android: прослушать приложение, установленное / обновленное широковещательное сообщение Захват нажатия клавиш, когда телефон Android работает в глубоком спящем режиме Изменение ActionBar при использовании фрагментов

Виджет не удаляется при передаче RESULT_CANCELED в качестве результата для активности конфигурации

У меня проблемы с моими виджетами. Вот описание:

Контекст:

У меня есть домашний виджет.

Когда я добавляю его, он создает настройку Activity для установки некоторых параметров для виджета.

Если я вызываю setResult (RESULT_OK, resultValue); Перед завершением настройки Activity виджет добавляется в Home.

Если я удалю виджет, перетащив его в корзину мусора, вызывается public void onDeleted (контекст контекста, int [] appWidgetIds) из моего класса AppWidgetProvider. Все идет нормально.

Проблема. Если действие «Конфигурация» завершается с кодом результата RESULT_CANCELED ( setResult (RESULT_CANCELED); ), public void onDeleted (контекст контекста, int [] appWidgetIds) из моего класса AppWidgetProvider не вызывается и виджет остается в списке активных виджетов. Когда я перезапускаю телефон, вызывается onUpdate (контекст контекста, AppWidgetManager appWidgetManager, int [] appWidgetIds) из моего класса AppWidgetProvider и в int [] appWidgetIds у меня есть все виджеты (ids), которые должны быть отменены (удалены перед добавлением) + Активные (те, которые фактически отображаются на Домашней странице). Виджеты, которые были удалены путем перетаскивания в корзину мусора, не отображаются в этом списке. Со временем этот список идентификаторов виджетов продолжает становиться все больше и больше, если пользователь отменяет настройку Activity.

Ссылка API говорит следующее: «Если вы вернете RESULT_OK с помощью Activity.setResult (), AppWidget будет добавлен, и вы получите ACTION_APPWIDGET_UPDATE для этого AppWidget. Если вы вернете RESULT_CANCELED, хост отменит добавление и не отобразит Этот AppWidget, и вы получите трансляцию ACTION_APPWIDGET_DELETED ».

Может ли кто-нибудь дать мне некоторые намеки на это? Спасибо.

Вот мой манифест:

<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> <receiver android:name=".MytWidget" android:label="@string/app_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_widget_provider" /> </receiver> <activity android:name=".ConfigurationActivity"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> </intent-filter> </activity> </application> 

Остальная часть кода не имеет значения, поскольку она была объяснена выше (и у меня нет разрешения на ее публикацию).

Solutions Collecting From Web of "Виджет не удаляется при передаче RESULT_CANCELED в качестве результата для активности конфигурации"

У меня была такая же проблема, я сделал это на событии onPause

 public void removeWidget(int appWidgetId) { AppWidgetHost host = new AppWidgetHost(Config.this, 1); host.deleteAppWidgetId(appWidgetId); } 

Проверьте идентификаторы виджета, виджет удален. Идентификатор хоста не важен, если у вас есть только один виджет приложения.

 private boolean canceled = true; @Override protected void onPause() { if(canceled) { removeWidget(appWidgetId); } super.onPause(); } 

В OK нажмите, я установил canceled false

Вы уверены, что ваш код не имеет значения? Все в вашем манифесте выходит из книги и выглядит хорошо. Ваш код должен выглядеть очень похоже на это:

  public void configCancelOnClick(View v) { MyLog.d(TAG, "configCancelOnClick"); Intent intent = new Intent(); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_CANCELED, intent); finish(); } 

PutExtra требуется сообщить os, который виджет вы не создаете … Для завершения нужно закончить. Если у вас его нет, вы не получите намерения, переданные операционной системе, и потеряете setResult.

Наконец, когда конфигурация не выполняется корректно (обратная клавиша, домашний ключ или плохой код), создается виджет-призрак. Даже с совершенным кодом, если пользователь нажимает на домашний ключ во время настройки, у вас будет виджет, стоящий в очереди на систему, которая на самом деле не существует на любом домашнем экране. Вот почему я называю их призраками. Как только виджет успешно завершит настройку, он будет вызывать onDeleted при удалении с главного экрана. У вас осталась проблема, что если призраки были созданы, onDisabled никогда не будет запущен.

Последняя проверка. Поскольку выполняется config, в вашем информационном файле xml есть следующее. Но на всякий случай это выглядит так:

  android:configure=your.package.name.ConfigurationActivity" 

Я решил эту проблему следующим образом:

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

 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); for(final int appWidgetId : appWidgetIds) { final StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(appWidgetId); stringBuilder.append("_conf"); if(context.getSharedPreferences("settings",0).getBoolean(stringBuilder.toString(),false)) updateAppWidget(context,appWidgetId,appWidgetManager); } } 

Кажется, с возрастом много проблем с виджетами. При этом при поиске решения одной из них я наткнулся на это сообщение: https://code.google.com/p/android/issues/detail?id=2539#c15

В основном идея состоит в том, чтобы удалить активность приложения из манифеста и проверить во время onUpdate, если виджет настроен, если не открыть активность конфигурации.

Он полностью прозрачен для пользователя и, как говорят, исправляет проблему «добавить / зомби». Попробуем это сейчас.


Однако это не решает проблему с удаленными виджетами, обновляемыми при перезагрузке, даже несмотря на то, что в последних версиях Android они были исправлены (4.4+ не уверены, какой?).

В более старых версиях Android я заметил, что все виджеты, которые я вручную удалил из программы запуска, превращаются в зомби при перезагрузке, OS эффективно вызывает onUpdate для каждого из этих виджетов, поэтому мне пришлось сохранить список удаленных виджета.

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