【发布时间】:2018-02-27 22:03:21
【问题描述】:
我正在创建一个测试小部件,通过单击其按钮来显示随机数。一切都在我的Provider 的onUpdate 内,包括pendingIntent。它工作正常,但重启手机后views.setOnClickPendingIntent 无法正常工作,虽然RemoteViews 重新创建没有问题,但按钮变得无响应。
public class TestWidget extends AppWidgetProvider {
static HashMap<Integer, BroadcastReceiver> br = new HashMap<>();
static void updateAppWidget(Context context, final AppWidgetManager appWidgetManager,
final int appWidgetId) {
context = context.getApplicationContext();
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
views.setTextViewText(R.id.appwidget_text, Math.random() + "");
appWidgetManager.updateAppWidget(appWidgetId, views);
}
};
br.put(appWidgetId, broadcastReceiver);//to unregister later
Intent intent = new Intent("action");
IntentFilter intentFilter = new IntentFilter("action");
context.registerReceiver(broadcastReceiver, intentFilter);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.appwidget_button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
context.unregisterReceiver(br.get(appWidgetId));
}
}
}
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aeza.sta">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<receiver android:name=".TestWidget" android:enabled="true" android:exported="false" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/test_widget_info" />
</receiver>
<activity android:name=".TestWidgetConfigureActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
</application>
</manifest>
【问题讨论】:
-
为那个广播动态注册你的接收器充其量是不稳定的。我有点惊讶它完全有效。 Anyhoo,
AppWidgetProvider只是一个专门的BroadcastReceiver。如果您希望您的TestWidget类处理该点击,只需为TestWidget创建一个显式Intent,并可选择设置一些独特的操作String。然后,您可以覆盖onReceive(),检查传递的Intent是否没有任何操作 - 或您的唯一操作,无论哪个 - 如果有,请进行刷新。 -
如果没有,则调用
super.onReceive(context, intent);,然后AppWidgetProvider会将广播委托给适当的Widget 方法。所有 Widget 广播都将具有非空操作。 -
是的,谢谢,你是对的,似乎动态地“以这种方式”注册我的接收器是完全错误的,我认为在提供者自己的接收器中创建小部件是标准方式。
-
如果有的话我会选择最佳答案
-
重启后,恢复状态的最好方法是使用onEnabled。因此,您可以在 onEnabled 上设置一个新的 RemoteViews,您的小部件将像以前一样响应。正如有人之前所说,在您的 AppWidgetProvider 中的 OnReceive 中对您的点击进行反击
标签: android widget broadcastreceiver android-pendingintent