После того, как кнопки изменения ориентации на виджете не отвечают

У меня есть две кнопки на виджетах, которые меняют некоторые элементы в виджетах, если ориентация меняется на телефоне, кнопки ничего не делают. Я читал http://developer.android.com/guide/topics/resources/runtime-changes.html, но все это касается активности, а не виджета.

@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); Intent active = new Intent(context, TvWidget.class); active.setAction(ACTION_WIDGET_RECEIVER); mDbHelper = new DbAdapter(context); fillChannelList(context, appWidgetIds[appWidgetIds.length-1]); Set<Integer> keys = channelsImages.keySet(); Iterator<Integer> iter = keys.iterator(); while(iter.hasNext()) { if(channelId == 0) { channelId = iter.next(); break; } } SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0); Editor edit = settings.edit(); edit.putInt("channelId", channelId); edit.putInt("appWidgetIds", appWidgetIds[appWidgetIds.length-1]); edit.commit(); active.putExtra("net.aerosoftware.tvvodic.appWidgetIds", appWidgetIds); PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0); remoteViews.setOnClickPendingIntent(R.id.button_next, actionPendingIntent); Intent refresh = new Intent(context, TvWidget.class); refresh.setAction(ACTION_WIDGET_REFRESH); refresh.putExtra("net.aerosoftware.tvvodic.appWidgetIds", appWidgetIds); PendingIntent refreshPendingIntent = PendingIntent.getBroadcast(context, 0, refresh, 0); remoteViews.setOnClickPendingIntent(R.id.button_refresh, refreshPendingIntent); updateView(context); appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); super.onUpdate(context, appWidgetManager, appWidgetIds); } 

Solutions Collecting From Web of "После того, как кнопки изменения ориентации на виджете не отвечают"

Я бы предложил создать службу (возможно, подклассифицировав ее внутри вашего AppWidgetProvider) и переопределив метод onConfigurationChanged (). Использование службы позволит вам делегировать вашу бизнес-логику для обработки, сборки и обновления вашего виджета. Он также позволит вам управлять поворотами. И если вы выполняете какие-либо операции блокировки, то сервис будет хорошим местом для создания потока и возврата результата к основному потоку пользовательского интерфейса, чтобы избежать ANR.

Я бы предложил следующее:

 public class MyWidget extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { context.startService(new Intent(context, MyUpdateService.class)); } public static class MyUpdateService extends Service { @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); // Update the widget RemoteView remoteView = buildRemoteView(this); // Push update to homescreen pushUpdate(remoteView); // No more updates so stop the service and free resources stopSelf(); } public RemoteViews buildRemoteView(Context context) { RemoteView updateView = null; updateView = new RemoteViews(context.getPackageName(), R.layout.my_widget_layout); // Your code to build and update the remote view return updateView; } @Override public void onConfigurationChanged(Configuration newConfig) { int oldOrientation = this.getResources().getConfiguration().orientation; if(newConfig.orientation != oldOrientation) { // Update the widget RemoteView remoteView = buildRemoteView(this); // Push update to homescreen pushUpdate(remoteView); } } private void pushUpdate(RemoteView remoteView) { ComponentName myWidget = new ComponentName(this, MyWidget.class); AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(myWidget, updateViews); } } } 

Также ознакомьтесь с этой ссылкой: http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html

Также не забудьте указать, что вы заинтересованы в получении уведомлений об изменении ротации в вашем манифесте. Что-то вроде этого будет работать: android: configChanges = "keyboardHidden | orientation", объявленный в вашей декларации сервиса внутри манифеста.

Надеюсь, это поможет!

Всякий раз, когда вы обновляете внешний вид своего виджета (используя либо Activity, либо ваш широковещательный приемник [поставщик виджета приложений]), вы также должны переназначить все PendingIntents для обработчиков кликов, а затем вызвать updateAppWidget() как обычно.

Пример с setTextViewText() :

 // This will update the Widget, but cause it to // stop working after an orientation change. updateWidget() { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); remoteViews.setTextViewText(R.id.widget_text_view, "Updated widget"); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } // This is the correct way to update the Widget, // so that it works after orientation change. updateWidget() { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); remoteViews.setTextViewText(R.id.widget_text_view, "Updated widget"); Intent intent = new Intent(context, MyWidgetActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, ...); remoteViews.setOnClickPendingIntent(R.id.widget_click_button, pendingIntent); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } 

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

http://permalink.gmane.org/gmane.comp.handhelds.android.devel/98008

или

http://groups.google.com/group/android-developers/browse_thread/thread/578a4429c369c27c/273a53a96ddd10c5?lnk=gst&q=Widget+does+not+respond+when+phone+orientation+changes#273a53a96ddd10c5

Но пока не ясно, что такое истинное решение (решение, которое не требует создания фоновой службы).

Если вы используете

 RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 

Для изменения некоторого состояния определенного вида внутри объекта удаленных представлений вам нужно также изменить другие представления, поскольку событие изменения ориентации будет помнить только последний объект RemoteViews, который использовался для обновления вашего виджета. Он воссоздает виджет с последним используемым объектом RemoteViews. Вот почему вам всегда нужно обновлять все виды внутри объекта RemoteViews, а также всех слушателей для ваших просмотров.

Остальное будет обрабатываться ОС автоматически.