2012-05-13 54 views
1

私はAndroidウィジェットを手に入れるために非常に簡単なコードを試していますが、運はありません。私は周りを見回し、良い答えを見つけていない。Androidウィジェットがタッチに反応しない

私が望むのは、ウィジェットがタッチされて現在の値が表示されているときにカウンタをインクリメントすることです。

これは私のAppWidgetProviderです:

public class WordWidget extends AppWidgetProvider 
{ 
    Integer touchCounter = 0; 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    { 
     //This is run when a new widget is added or when the update period expires. 
     Log.v("wotd", "Updating " + appWidgetIds.length + " widgets"); 

     for(int x = 0; x < appWidgetIds.length; x++) 
     { 
      Integer thisWidgetId = appWidgetIds[x]; 

      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); 
      remoteViews.setTextViewText(R.id.mainText, touchCounter.toString()); 

      Intent widgetIntent = new Intent(context, WordWidget.class); 
      widgetIntent.setAction("UPDATE_NUMBER"); 

      PendingIntent widgetPendingIntent = PendingIntent.getBroadcast(context, 0, widgetIntent, 0); 

      remoteViews.setOnClickPendingIntent(R.id.widgetLinearLayout, widgetPendingIntent); 
      appWidgetManager.updateAppWidget(thisWidgetId, remoteViews); 
     } 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     Log.v("wotd", "In onReceive with intent=" + intent.toString()); 
     if (intent.getAction().equals("UPDATE_NUMBER")) 
     { 
      Log.v("wotd", "In UPDATE_NUMBER"); 
      touchCounter++; 
      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); 
      remoteViews.setTextViewText(R.id.mainText, touchCounter.toString()); 
     } else 
     { 
      Log.v("wotd", "In ELSE... going on to super.onReceive()"); 
      super.onReceive(context, intent); 
     } 
    } 
} 

これが私のマニフェストの一部です:

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 

    <receiver 
     android:icon="@drawable/ic_launcher" 
     android:name="com.example.mywidget.WordWidget" 
     android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
      <action android:name="UPDATE_NUMBER" /> 
     </intent-filter> 

     <meta-data 
      android:name="android.appwidget.provider" 
      android:resource="@xml/widgetinfo" /> 
    </receiver> 

</application> 

ログはonReceive()がすぐにホーム画面に配置された後、と後に呼ばれる示し触れられているが、数字は決して増加しない。私はウィジェットの仕組みを完全には理解していませんが、それらはonUpdate()の後に殺されていますか?だからこれを行うには、何らかの永続的なストレージを使用する必要がありますか?

また、私が現在別のウィジェットを追加している場合、両方に同じ値が表示され、1つだけタッチしても増分します。どのウィジェットにも自分のカウンターを持たせる方法はありますか?

ありがとうございます!

答えて

11

実際にあなたの質問に答えました。しかし、いくつかを明確にしましょう:

A. AppWidgetsは、ホーム画面上にある限り、殺されません。しかし、彼らはあなたのものではありません。彼らは自宅のアプリケーションのプロセスで実行されています。具体的には、ホームアプリケーションのプロセスでビューが実行されているため、ウィジェットは表示されますが、期待どおりに動作しないため、ビューの代わりにRemoteViewを使用して、ウィジェットを更新しています。

B.一方、AppWidgetProviders(あなたの場合はWordWidgetクラス)は、onReceiveメソッドが終了するとすぐに破棄されます。 onReceiveメソッドが呼び出されるたびに、それらの変数はすべて再初期化されます。これがあなたの人数が増えない理由です。 AppWidgetProviderの目的は、ウィジェットのRemoteViewを更新し、アプリケーションに登録されたブロードキャストが到着したことを通知することです。

C. AppWidgetProviderのonUpdateメソッドは、更新が必要なウィジェットIDを持つ配列を提供します。これは、ウィジェットインスタンスの数とそのIDを取得するために使用できる唯一のコードポイントです。 RemoteViewsのため、あなたのウィジェットのビューから有用な価値を得る方法はありません(例えば、あなたはTextViewからカウンター値を読み取ることができません)ので、提供された情報を使用しなければなりません。DOを持続するウィジェットid。次のonUpdateが呼び出されると、ストレージから値を読み込み、値を大きくし、ウィジェットを新しい値で更新してから、新しい値を元に戻します。

D.ウィジェットが自分自身を更新するときにウィジェットが多くのことをしたり、遅く(ネットワーキングのように)しなければならない場合は、サービスを使用することを検討する必要があります。しかし、あなたのケースでは(数字を増やすために)、永続的なストレージや他の場所にカウンタを保持している限り、あなたのアプローチはうまくいきます。

最後に、あなたのonReceiveオーバーライドでは、 "UPDATE_NUMBER"アクションを受信しない場合にのみ "super.onReceive"を呼び出していることに気付きました。良い理由がない限り(それは別の話です)、あなたのオーバーライドの最初または最後のコマンドとして常にsuper.onReceiveを呼び出します。

希望します。

+0

大変ありがとうございます!私はブログ記事を読んでから何時間もあなたに答えました。 onReceive()メソッドの最初または最後のコマンドとしてsuper.onReceive()を呼び出すことの違いは何ですか?私はいつもスーパーに関してこの質問をしてきました。 – Sandy

+2

実際それはあなたが何をしているかによって異なります。たとえば、return(; returnを呼び出して)を途中で終了させたい場合は、最初に(戻り呼び出しの前に)superを呼び出す必要があります。しかし、Androidには、super.onDestroyを最初に呼び出さなければならない他のメソッドがあります(よく覚えていれば、ActivityのonDestroy)。私のアプリウィジェットでは、最後のコマンドとしてsuper.onReceiveを呼び出しています... – Christos

+0

onReceive()では、touchCounterをランダムな値に等しくなるように変更しました。(touchCounter = new Random()。nextInt(100);) onUpdate()でTextViewが変更されたときにコメントアウトしても値は変更されません。他に何かが足りないのですか? – Sandy

関連する問題