先日のATM手数料ウィジェットを作成する際に、配置時に設定画面を表示して、ウィジェットの指定を行うように作っていたのですが、その設定画面で指定したデータをウィジェットに渡す際に思った以上に、詰まってしまったので今回行った方法を覚書しておきます。
初めに、ウィジェット設置の際に設定画面を表示させる場合には、”android.appwidget.provider”のXML内、”appwidget-provider”要素に以下の属性を指定すれば可能です。
android:configure="呼び出すActivityのフルパス"
そして、Androidmanifestに以下のようにActivityの設定を行います。
そして、これで表示される設定画面からウィジェット本体に設定を渡すようにしますが、この設定表示方法で設定を行う場合、ウィジェット本体にデータを渡す必要があります。 今回はその設定にPreferenceを利用しました。ウィジェットは複数配置する可能性もありうるため、この場合Preferenceはウィジェット毎に個別の物を用意する必要があります。
今回はこちらのサイトさんを参考にPreferenceの作成時に各ウィジェット固有のIDを渡すことによってその設定を行っています。
SharedPreferences pref = getSharedPreferences( "Widget" + AppWidgetId, MODE_PRIVATE);
Editor e = pref.edit();
e.putString("データタグ", "設定データ");
e.commit();
そして、ウィジェット本体側で同様にPreferenceからデータを受け取ります。
SharedPreferences pref = context.getSharedPreferences("Widget" + appWidgetId,android.content.Context.MODE_WORLD_READABLE);
String Data = pref.getString("データタグ", "データが存在しなかった時の代用値");
また、ウィジェット毎に設定を書き出すため、そのウィジェットを削除する時に(他で使わなければ)そのPreferenceを削除しておかなければ、ウィジェットを設置し直すたびにデータ領域を使用してしまいます。
今回はonDeletedにこちらのサイトさんを参考にした削除処理を加えています。
onDeletedに渡されているappWidgetIdsは削除されるウィジェットのIDの配列なので、foreach文で、まわして処理しています。
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
for (int appWidgetId: appWidgetIds) {
Log.v("HelloAndroidWidget", "onDeleted-ID");
SharedPreferences pref = context.getSharedPreferences("Widget"
+ appWidgetId, android.content.Context.MODE_WORLD_READABLE);
Editor e = pref.edit();
e.clear().commit();
}
}
正直なところ、同一のアプリ内でのデータの受け渡しを行うために、別途データ保存用のデータ領域を使ってデータを受け渡しするのは、若干無駄な感じがしていて、引っかかりを感じてます。ですが現状私が行った分にはこの方法ぐらいしかうまくいかず、仕様上ウィジェットの更新時にもこの値は必要であり、結局常時保存が必要であることには変わりがなかったため、とりあえずこの方法で前回のアプリは実装しました。
どなたかもっとスマートな方法があったら教えてください…