Androidのホーム画面に複数のWidgetを配置して、タップしたWidgetに応じてアプリ起動時の処理を分けたい時があると思います。
以下の画像のように、選択したWidgetに応じてアプリ起動時のタスク名を変更する実装について書いていきたいと思います。
タップされたappWidgetIdを渡す
実装は以下の通りです。
public class ToDoAppWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.todo_appwidget);
Intent titleIntent = new Intent(context, ToDoMainActivity.class);
titleIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
titleIntent.putExtra(ToDoAppWidgetConfigure.SELECT_WIDGET_GROUP_ID, appWidgetId);
titleIntent.setData(Uri.parse(titleIntent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent titlePendingIntent = TaskStackBuilder.create(context)
.addNextIntentWithParentStack(titleIntent)
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
views.setOnClickPendingIntent(R.id.todo_widget_title_view, titlePendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
Widgetにタップされた時の動作を付けるには、WidgetのViewにPendingIntentをセットします。PendingIntentはトリガーとなるイベント発火時に実行されるIntentとなり、通常のIntentと同様にputExtraできます。
ですが、重要なのが以下。
titleIntent.setData(Uri.parse(titleIntent.toUri(Intent.URI_INTENT_SCHEME)));
通常のIntent同様にputExtraだけの設定をすると、複数のWidgetを配置しても最後に配置したWidgetに対してのputExtraしか保持してくれません。そのため、上記の行を設定する事で、Widget毎のputExtraを保持してくれる、つまりWidget毎のappWidgetIdが設定できます。
公式ドキュメントにも以下のように記載されていました。
インテントを比較すると、エクストラは無視されるため、エクストラが無視されないようにデータにエクストラを埋め込む必要があります。
上記実装をしたアプリ
上記の実装をしたウィジェット機能付きの記録が残るToDoリストを是非利用してみて下さい。
また、ソースコードも公開しているのでぜひ参考にしてもらえればと思います。

