Android - 带有 Remoteviews 的 Appwidget 在重启后不更新

标签 android android-appwidget remoteview appwidgetprovider samsung-touchwiz

我在 SO 上看到了类似的问题,但在我的情况下似乎没有任何效果......

我创建了一个带有 AdapterViewFlipper 的 appwidget(简单的 ViewAnimator,它将在已添加到其中的两个或多个 View 之间进行动画处理)。 appwidget 有一个 Next 按钮,使用户能够导航到 widget 上的下一个 View 。

当我第一次添加 appwidget 时一切正常。但是如果智能手机重新启动,小部件的下一步按钮将不再适用于我的三星 S4(方法 onReceive 被调用,但没有任何反应,它不会导航到下一个 View 并停留在第一个 View )。我必须删除小部件并再次添加它才能使其正常工作...

我怀疑这是 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;
}
}

list

<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" />

如有任何帮助,我们将不胜感激!

最佳答案

取决于启动器,无法保证您的 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  
    }
}

关于Android - 带有 Remoteviews 的 Appwidget 在重启后不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34556834/

相关文章:

android - Android上的UDP客户端

android - 在 ubuntu 上安装 android studio

android - 以编程方式在堆栈小部件中显示下一个/上一个图像

Android:将 WebView 输出加载到 App Widget

android - RemoteViews 在 View 类中不起作用

android - 未检测到我的 MotionEvent.ACTION_DOWN

android - 是否有可能使用 Reader SDK 以编程方式更改方形键?

android - 如何观察内容提供者的变化?安卓

android - Glide : load image to push notifications

android - RemoteView 不在自定义通知中显示按钮