2012-01-17 104 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); 
} 
} 

謝謝。

相關問題