Android - Appwidget с Remoteviews не обновляется после перезагрузки
Я видел подобные вопросы здесь на SO, но, кажется, ничего не работает в моем случае...
Я создал приложение с AdapterViewFlipper
(Простой ViewAnimator, который будет анимировать между двумя или более представлениями, которые были добавлены к нему). В виджете приложения есть кнопка "Далее", позволяющая пользователю перейти к следующему представлению в виджете.
Все отлично работает, когда я впервые добавляю appwidget. Но если смартфон перезагружается, кнопка "Далее" виджета больше не работает на моем Samsung S4 (метод onReceive
вызывается, но ничего не происходит, он не переходит к следующему представлению и застревает при первом просмотре). Я должен удалить виджет и добавить его снова, чтобы он работал...
Я подозреваю, что это проблема Touchwiz, так как я тестировал его на другом телефоне (Moto G), и он работал нормально.
Вот некоторые части моего кода:
AppWidgetProvider
public class AppWidgetProvider extends AppWidgetProvider {
public static final String NEXT_ACTION = VersionUtil.getPackageName() + ".action.NEXT";
private static final String TAG = DailyAppWidget.class.getSimpleName();
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId, colorValue);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, int primaryColor) {
Intent intent = new Intent(context, ViewFlipperWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
// Instantiate the RemoteViews object for the app widget layout.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.app_widget);
// open the activity from the widget
Intent intentApp = new Intent(context, MainActivity.class);
intentApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intentApp, 0);
rv.setOnClickPendingIntent(R.id.widget_title, pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
rv.setRemoteAdapter(R.id.adapter_flipper, intent);
} else {
rv.setRemoteAdapter(appWidgetId, R.id.adapter_flipper, intent);
}
// Bind the click intent for the next button on the widget
final Intent nextIntent = new Intent(context,
AppWidgetProvider.class);
nextIntent.setAction(AppWidgetProvider.NEXT_ACTION);
nextIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
final PendingIntent nextPendingIntent = PendingIntent
.getBroadcast(context, 0, nextIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.widget_btn_next, nextPendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, mRemoteViews);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(NEXT_ACTION)) {
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.daily_app_widget);
rv.showNext(R.id.adapter_flipper);
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
Log.e(TAG, "onReceive APPWIDGET ID " + appWidgetId);
AppWidgetManager.getInstance(context).partiallyUpdateAppWidget(
appWidgetId, rv);
}
super.onReceive(context, intent);
}
обслуживание
public class FlipperRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private Context mContext;
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private static final String TAG = "FILPPERWIDGET";
public FlipperRemoteViewsFactory(Context context, Intent intent) {
mContext = context;
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
//... get the data
}
@Override
public void onCreate() {
Log.e(TAG, "onCreate()");
}
@Override
public void onDataSetChanged() {
Log.i(TAG, "onDataSetChanged()");
}
@Override
public void onDestroy() {
}
@Override
public int getCount() {
//... return size of dataset
}
@Override
public RemoteViews getViewAt(int position) {
Log.i(TAG, "getViewAt()" + position);
RemoteViews page = new RemoteViews(mContext.getPackageName(), R.layout.app_widget_item);
//... set the data on the layout
return page;
}
@Override
public RemoteViews getLoadingView() {
Log.i(TAG, "getLoadingView()");
return new RemoteViews(mContext.getPackageName(), R.layout.appwidget_loading);
}
@Override
public int getViewTypeCount() {
Log.i(TAG, "getViewTypeCount()");
return 1;
}
@Override
public long getItemId(int position) {
Log.i(TAG, "getItemId()");
return position;
}
@Override
public boolean hasStableIds() {
Log.i(TAG, "hasStableIds()");
return true;
}
}
манифест
<receiver android:name=".AppWidgetProvider"
android:label="@string/app_name"
android:enabled="@bool/is_at_least_12_api">
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/app_widget_info" />
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
</receiver>
<!-- Service serving the RemoteViews to the collection widget -->
<service android:name=".ViewFlipperWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS"
android:exported="false" />
информация о приложении
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/app_widget"
android:initialLayout="@layout/app_widget"
android:minHeight="110dp"
android:minWidth="250dp"
android:previewImage="@drawable/widget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="14400000"
android:widgetCategory="home_screen" />
Любая помощь будет оценена!
1 ответ
Зависит от лаунчера, нет гарантии что ваш AppWidget
будет обновлено сразу после запуска устройства. Это может быть обновлено немедленно или подождать, пока updatePeriodMillis
прошло после запуска системы.
Чтобы решить вашу проблему, определите BroadcastReceiver
это вызовет обновление AppWidget
после перезагрузки.
В AndroidManifest.xml
определить BootReceiver
чтобы получить сообщение boot_complete.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
И определить BootReceiver.java
начать свой AppWidgetUpdateService
public class BootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
//start appwidget update service
}
}