2012-01-17 4 views
0

私は、ボタンクリックでトーストを表示する、非常に簡単なホーム画面ウィジェットアプリケーションを持っています。幸いにも、パワーアップ時(またはエミュレータで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によって呼び出されていない見ることができるようにおしゃれな機能...

私にこれを手伝ってもらえますか?

ありがとうございました。

答えて

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に設定されたアクションでインテントを作成するだけでは、super.onReceive()呼び出しによってmy override onUpdate()関数の呼び出しを開始するには不十分です。 AppWidgetProviderクラスのonReceive()関数のコードによると、インテントフィールドにはいくつかのデータが含まれている必要があります。だから、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); 
} 
} 

ありがとうございます。

関連する問題