Android widgetで2つのボタンを検知する方法

  •  

 

※画像は弊社『電卓』のウィジェットです。

Androidのウィジェットで2つのボタンを検知する方法。
1つだとサンプルソースがネット上に沢山ありますが、2つ以上だと無く、3時間程ハマったので。

ボタンのクリックイベントを拾う方法は色々ありますが、
今回は、ProviderでSerciseを起動。
ServiseでボタンのActionを紐付け。
という方法です。

縦画面固定であれば、ここまででOKです。
が、今回は横画面に切り替えた際もクリックイベントを検知したい。
ここで若干ハマりました。(というか良いサンプルが見つからなかった)

先ずはAppWidgetProviderでServiceを実行します。

public class SampleWidgetProvider extends AppWidgetProvider {

	public SampleWidgetProvider() {
	}

	@Override
	public void onEnabled(Context context) {
		super.onEnabled(context);
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		super.onReceive(context, intent);
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		// ホームウィジェットを処理するサービスの実行
		Intent service = new Intent(context, SampleWidgetService.class);
		context.startService(service);
	}

	public void onDisabled(Context context, Intent intent) {
		super.onDisabled(context);
		// サービスの停止
		Intent service = new Intent(context, SampleWidgetService.class);
		context.stopService(service);
	}
}

ServiceのonStart()で紐付けする際は、1つのIntentに複数追加しても正常動作します。
が、横画面に切り替えた際、on〜Changed()で同じように1つのIntentに複数追加すると、最後に追加したボタンしか検知できません。

クリックのActionはIntent毎に紐付けしています。
なのでボタンの数だけIntentを発行すればOK。

ソースはこんな感じ。
onStart()でボタンクリックを紐付けして、onConfigurationChanged(Configuration newConfig)で画面回転時など再度紐付けしています。

public class SampleWidgetService extends Service {
	private static final String ACTION_1 = "com.example.samplewidget.SampleWidgetService.ACTION_1";
	private static final String ACTION_2 = "com.example.samplewidget.SampleWidgetService.ACTION_2";

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// 画面回転時等
		Context context = getBaseContext();
		Intent buttonIntent1 = new Intent(context, SampleWidgetService.class);
		Intent buttonIntent2 = new Intent(context, SampleWidgetService.class);
		PendingIntent pendingIntent1 = PendingIntent.getService(context, 0, buttonIntent1, PendingIntent.FLAG_UPDATE_CURRENT);
		PendingIntent pendingIntent2 = PendingIntent.getService(context, 0, buttonIntent2, PendingIntent.FLAG_UPDATE_CURRENT);

		RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);

		remoteViews.setOnClickPendingIntent(R.id.btn1, pendingIntent1);
		remoteViews.setOnClickPendingIntent(R.id.btn2, pendingIntent2);

		// AppWidgetの画面更新
		ComponentName thisWidget = new ComponentName(context, SampleWidgetProvider.class);
		AppWidgetManager manager = AppWidgetManager.getInstance(SampleWidgetService.this);
		manager.updateAppWidget(thisWidget, remoteViews);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		Context context = getBaseContext();
		Intent buttonIntent1 = new Intent(context, this);
		Intent buttonIntent2 = new Intent(context, this);
		buttonIntent1.setAction(ACTION_1);
		buttonIntent2.setAction(ACTION_2);
		PendingIntent pendingIntent1 = PendingIntent.getService(this, 0, buttonIntent1, 0);
		PendingIntent pendingIntent2 = PendingIntent.getService(this, 0, buttonIntent2, 0);

		RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.widget);

		remoteViews.setOnClickPendingIntent(R.id.btn1, pendingIntent1);
		remoteViews.setOnClickPendingIntent(R.id.btn2, pendingIntent2);

		if (ACTION_1.equals(intent.getAction())) {
			setVal("1", remoteViews);
		}
		if (ACTION_2.equals(intent.getAction())) {
			setVal("2", remoteViews);
		}

		// AppWidgetの画面更新
		thisWidget = new ComponentName(this, SampleWidgetProvider.class);
		manager = AppWidgetManager.getInstance(this);
		manager.updateAppWidget(thisWidget, remoteViews);
	}
}

分かってしまえば(というかソースをちゃんと理解すれば)簡単なことなのですが。

ネットにソースを公開してる人って、ちゃんと理解してないんでしょうね。
ソースのコメントやエントリー内容に惑わされました。
※もちろん俺もとりあえず書いて期待通りの動作をすればOKで、細部まで深く理解しようとなんて思っていません。時間の無駄。

株式会社woodsmallの小林でした。
https://woodsmall.co.jp

関連記事

コメント

この記事へのコメントはありません。

TOP