AppWidget 在多个设备上停止工作
AppWidget stopped working in several devices
我有一个 android 应用程序,它基本上是一个用于巴西东南部降雨检测的应用程序小部件。自推出以来一直运行良好,但突然在多个设备上停止运行。
appwidget 不再响应任何触摸。它在我的 phone(扩展了 AOSP 的 Lenovo K6)上运行良好,但我收到许多 Motorola/Samsung phone 的报告,该小部件只是冻结了。重启设备或重新安装应用程序均未解决。
由于我无法在我的 phone 或模拟器中重现该问题,因此找到问题源让我很头疼。一件重要的事情是,在我将 targetSdkVersion 更改为 26 后,小部件停止工作,这是去年 Google 要求的。不知道有没有关系,差不多是同时发生的
我在下面附加了我的小部件 class 的部分,它处理更新和设置按钮的意图(我省略了带有 /* ... */ 的部分,因为代码将是此处太冗长且令人困惑):
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 方法中是否引发了任何异常,但显然没有引发任何异常。
非常感谢您的帮助!
听起来您可能没有使用 运行 Oreo 设备进行测试。
Oreo 引入了 severe limitations 隐式广播(未在 Intent 上设置组件或包)。如果您有设备 运行 Oreo,并且您的应用以 Oreo 为目标,您将达到这些限制。如果您的应用以 Nougat and/or 为目标,那么您 运行 Nougat 或更低版本,您将不会注意到它们。
你应该很容易解决这个问题。
当您构建包装的 Intent 时,请改用它:
Intent intent = new Intent(context, RadarWidget.class);
intent.setAction("com.comodo.weatherpal.ACTION_UPDATE_WIDGET");
其余代码可以保持不变。这只是确保 Intent 明确针对您的 RadarWidget class,因此 Android 不会阻止它执行。
我有一个 android 应用程序,它基本上是一个用于巴西东南部降雨检测的应用程序小部件。自推出以来一直运行良好,但突然在多个设备上停止运行。
appwidget 不再响应任何触摸。它在我的 phone(扩展了 AOSP 的 Lenovo K6)上运行良好,但我收到许多 Motorola/Samsung phone 的报告,该小部件只是冻结了。重启设备或重新安装应用程序均未解决。
由于我无法在我的 phone 或模拟器中重现该问题,因此找到问题源让我很头疼。一件重要的事情是,在我将 targetSdkVersion 更改为 26 后,小部件停止工作,这是去年 Google 要求的。不知道有没有关系,差不多是同时发生的
我在下面附加了我的小部件 class 的部分,它处理更新和设置按钮的意图(我省略了带有 /* ... */ 的部分,因为代码将是此处太冗长且令人困惑):
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 方法中是否引发了任何异常,但显然没有引发任何异常。
非常感谢您的帮助!
听起来您可能没有使用 运行 Oreo 设备进行测试。
Oreo 引入了 severe limitations 隐式广播(未在 Intent 上设置组件或包)。如果您有设备 运行 Oreo,并且您的应用以 Oreo 为目标,您将达到这些限制。如果您的应用以 Nougat and/or 为目标,那么您 运行 Nougat 或更低版本,您将不会注意到它们。
你应该很容易解决这个问题。
当您构建包装的 Intent 时,请改用它:
Intent intent = new Intent(context, RadarWidget.class);
intent.setAction("com.comodo.weatherpal.ACTION_UPDATE_WIDGET");
其余代码可以保持不变。这只是确保 Intent 明确针对您的 RadarWidget class,因此 Android 不会阻止它执行。