我有一个相当简单的主屏幕小部件应用程序,它在按钮点击时显示Toast。幸运的是,它仅在启动时显示Toast(或者在我在模拟器中更新apk之后)。按钮单击具有发送ACTION_APPWIDGET_UPDATE的挂起意图,但基类的onReceive()函数不处理它。
这是我的代码:
public class WordWidget extends AppWidgetProvider {
@Override
public void onReceive(Context ctxt, Intent intent) {
Log.d("WordWidget.onReceive", "onReceive");
Log.d("WordWidget.onReceive", intent.getAction());
if (intent.getAction()==null) {
ctxt.startService(new Intent(ctxt, UpdateService.class));
} else {
super.onReceive(ctxt, intent);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// To prevent any ANR timeouts, we perform the update in a service
Log.d("WordWidget.onUpdate", "onUpdate");
context.startService(new Intent(context, UpdateService.class));
}
public static class UpdateService extends Service {
@Override
public void onStart(Intent intent, int startId) {
Log.d("UpdateService.onStart", "onStart");
// Build the widget update for today
RemoteViews updateViews = buildUpdate(this);
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this, WordWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
public RemoteViews buildUpdate(Context context) {
Log.d("UpdateService.buildUpdate", "buildUpdate");
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget_word);
Intent defineIntent = new Intent(context, WordWidget.class);
defineIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, defineIntent, 0);
updateViews.setOnClickPendingIntent(R.id.widget, pendingIntent);
showToast(context);
return updateViews;
}
private void showToast(Context context){
Log.d("UpdateService.showToast", "showToast");
Toast.makeText(context, "It is working...", Toast.LENGTH_LONG).show();
}
@Override
public IBinder onBind(Intent intent) {
// We don't need to bind to this service
return null;
}
}
}
在开机时(或刚刚重新安装后)我的小部件显示Toast,这是LogCat:
01-17 13:03:10.855: I/ActivityManager(72): Start proc com.example.android.simplewiktionary for broadcast com.example.android.simplewiktionary/.WordWidget: pid=564 uid=10036 gids={3003}
01-17 13:03:11.045: D/WordWidget.onReceive(564): onReceive
01-17 13:03:11.045: D/WordWidget.onReceive(564): android.appwidget.action.APPWIDGET_UPDATE
01-17 13:03:11.054: D/WordWidget.onUpdate(564): onUpdate
01-17 13:03:11.075: D/UpdateService.onStart(564): onStart
01-17 13:03:11.075: D/UpdateService.buildUpdate(564): buildUpdate
01-17 13:03:11.094: D/UpdateService.showToast(564): showToast
01-17 13:03:12.655: D/dalvikvm(72): GC_EXPLICIT freed 971K, 47% free 13550K/25159K, paused 7ms+52ms
现在一旦开始,如果我点击按钮,这里是LogCat:
01-17 13:04:16.095: D/dalvikvm(126): GC_EXPLICIT freed 72K, 14% free 14016K/16135K, paused 3ms+3ms
01-17 13:04:16.277: D/WordWidget.onReceive(564): onReceive
01-17 13:04:16.277: D/WordWidget.onReceive(564): android.appwidget.action.APPWIDGET_UPDATE
01-17 13:04:21.365: D/dalvikvm(564): GC_EXPLICIT freed 71K, 5% free 6307K/6595K, paused 3ms+2ms
正如您所看到的,onReceive()基类函数未调用onUpdate()...
你能帮我解决这个问题吗?
感谢。
答案 0 :(得分:3)
我终于找到了为什么我自己的onUpdate()没有被按钮点击上的super.onReceive()执行。
使用设置为ACTION_APPWIDGET_UPDATE的操作创建一个intent不足以通过super.onReceive()调用触发我的覆盖onUpdate()函数的调用。根据AppWidgetProvider类的onReceive()函数的代码,intent必须在extras字段中包含一些数据。这就是为什么第一次调用onUpdate()时(当它是来自系统的真实ACTION_APPWIDGET_UPDATE意图时),而不是当我点击按钮时......
以下是AppWidgetProvider.java文件中的代码:
// BEGIN_INCLUDE(onReceive)
public void [More ...] onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
}
else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
}
else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
}
else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
}
}
感谢。
答案 1 :(得分:0)
我建议您不要试图强制调用onUpdate
,而是设置PendingIntent
以启动服务:
Intent intent = new Intent(context, UpdateService.class);
PendingIntent pi = PendingIntent.getService(context, 0, intent, 0);
如果这不起作用或者对您来说不是一个可行的解决方案,请告诉我。