AppWidget停止在多个设备上工作

时间:2019-01-06 16:28:15

标签: android android-pendingintent android-appwidget

我有一个android应用程序,它基本上是巴西东南部雨水检测的应用程序。自推出以来,它一直运行良好,但是突然间,它停止了在多种设备中的工作。

该appwidget根本不再对任何触摸做出响应。它可以在我的手机上正常工作(带有AOSP扩展功能的联想K6),但是我收到了许多摩托罗拉/三星手机的报告,这些窗口小部件只是冻结了。重新启动设备或重新安装应用程序无法解决问题。

由于我无法在手机或仿真器上重现问题,因此寻找问题根源让我头疼。要说的一件事很重要,那就是在去年Google要求将targetSdkVersion更改为26之后,该小部件停止工作。我不知道它是否相关,但它几乎是在同一时间发生的。

我将我的小部件类的各个部分附加在下面,这些部分负责更新和设置按钮的意图(我用/ * ... * /省略了这些部分,因为代码太长且令人困惑) :

public class RadarWidget extends AppWidgetProvider {
    private static int noOfIntents = 4;

    /* ... */

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        RadarWidget.updateAppWidget(context, appWidgetManager, appWidgetId, null, null, null, null);
    }

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bitmap overlay, Bitmap background, String dateTimeString, String title) {
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.radar_widget);

        /* ... (read shared preferences) */

        views.setOnClickPendingIntent(R.id.radarwidget_syncbutton,
                getSyncPendingIntent(context, appWidgetId));
        views.setOnClickPendingIntent(R.id.radarwidget_gpsbutton,
                getToggleGPSPendingIntent(context, appWidgetId));
        views.setOnClickPendingIntent(R.id.radarwidget_rewbutton,
                getGoBackPendingIntent(context, appWidgetId));
        views.setOnClickPendingIntent(R.id.radarwidget_rewibutton,
                getGoBackPendingIntent(context, appWidgetId));
        views.setOnClickPendingIntent(R.id.radarwidget_ffbutton,
                getGoForwardPendingIntent(context, appWidgetId));
        views.setOnClickPendingIntent(R.id.radarwidget_ffibutton,
                getGoForwardPendingIntent(context, appWidgetId));

        /* ... (set texts, images, etc. on the widget) */

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        /* If received intent is one of ours (for widget update), use our logic */
        if (intent.getAction().equals("com.comodo.weatherpal.ACTION_UPDATE_WIDGET")) {
            /* ... (get extras from intent) */

            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

            if (widgetId != -1) {
                /* ... (perform some logic according to received extras, update shared preferences) */

                RadarWidget.updateAppWidget(context, appWidgetManager, widgetId, null, null,
                        context.getString(R.string.radarwidget_loadinglabel), null);
            }
        }
        /* Received intent is not one of ours for widget updating, send it to super */
        else {
            super.onReceive(context, intent);
        }
    }

    static PendingIntent getSyncPendingIntent(Context context, int widgetId) {
        Intent intent = new Intent("com.comodo.weatherpal.ACTION_UPDATE_WIDGET");
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        intent.putExtra("sync", true);
        return PendingIntent.getBroadcast(context, widgetId * noOfIntents, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    static PendingIntent getToggleGPSPendingIntent(Context context, int widgetId) {
        Intent intent = new Intent("com.comodo.weatherpal.ACTION_UPDATE_WIDGET");
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        intent.putExtra("toggleGPS", true);
        return PendingIntent.getBroadcast(context, widgetId * noOfIntents + 1, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    static PendingIntent getGoBackPendingIntent(Context context, int widgetId) {
        Intent intent = new Intent("com.comodo.weatherpal.ACTION_UPDATE_WIDGET");
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        intent.putExtra("goBack", true);
        return PendingIntent.getBroadcast(context, widgetId * noOfIntents + 2, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    static PendingIntent getGoForwardPendingIntent(Context context, int widgetId) {
        Intent intent = new Intent("com.comodo.weatherpal.ACTION_UPDATE_WIDGET");
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        intent.putExtra("goForward", true);
        return PendingIntent.getBroadcast(context, widgetId * noOfIntents + 3, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }
}

我一直在与一位受影响的用户交谈,我创建了一个特定的测试版本,在该版本中,我检查了updateAppWidget方法中是否引发了任何异常,但显然没有引发任何异常。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

听起来您可能没有在运行Oreo的设备上进行测试。

奥利奥(Oreo)在隐式广播中引入了severe limitations(在Intent上未设置组件或程序包)。如果您有运行Oreo的设备,并且您的应用程序以Oreo为目标,那么您将达到这些限制。如果您的应用程序以牛轧糖为目标和/或您正在运行牛轧糖或更低的牛轧糖,您将不会注意到它们。

您应该很容易解决这个问题。

构造包装的Intent时,请改用它:

@RestController

其余代码可以保持不变。这只是确保Intent明确针对您的RadarWidget类,因此Android不会阻止其执行。