2012-01-17 96 views
0

我有一个相当简单的主屏幕小部件应用程序,显示一个按钮点击吐司。幸运的是,它只在启动时显示Toast(或者在我更新模拟器中的apk之后)。按钮点击有一个挂起的意图发送ACTION_APPWIDGET_UPDATE,但基类的onReceive()函数不处理它。为什么基类onReceive()函数不会调用onUpdate()?

这里是我的代码:

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; 
     } 
    } 
} 

在上电(或只是后被重新安装)我的小部件显示敬酒,这里的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 

正如你可以看到的onUpdate()不被的onReceive()碱基C称为lass功能...

你能帮我吗?

谢谢。

回答

0

我会建议,而不是试图迫使onUpdate被调用,您将PendingIntent启动服务:

Intent intent = new Intent(context, UpdateService.class);  
PendingIntent pi = PendingIntent.getService(context, 0, intent, 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); 
} 
} 

谢谢。

相关问题