Tech Racho エンジニアの「?」を「!」に。
  • 開発

ACTION_SCREEN_ONを受け取る(2)

ACTION_SCREEN_ONを受け取るの続きです。

ACTION_SCREEN_ONを受け取るには、コードで明示的にregisterReceiverする必要がありました。

しかし、AppWidgetは表示時に生成されたあと、すぐに終了してしまいます。
コンストラクタでログを吐けば、onUpdate()とonDeleted()が呼ばれたときでは、それぞれでコンストラクタが呼ばれて、別のインスタンスが生成されるのが確認できると思います。

したがって、onUpdate()でregisterReceiverしてしまうと、終了時にunregisterReceiverする手段が無くなってしまうため、そのままでは使えません(どんどんReceiverが増えていきます)。

これを解決するには、サービスを使えば良さそうです。

たとえば以下のようなサービスを作っておいて、

public class ScreenStateService extends Service {
	private BroadcastReceiver mReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
				sendBroadcast(new Intent("jp.bpsinc.ScreenStateService.SCREEN_ON"));
			} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
				sendBroadcast(new Intent("jp.bpsinc.ScreenStateService.SCREEN_OFF"));
			}
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		getApplicationContext().registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
		getApplicationContext().registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
	}

	@Override
	public void onDestroy() {
		getApplicationContext().unregisterReceiver(mReceiver);
		super.onDestroy();
	}
}

AppWidgetProviderのonUpdate()で、このサービスを起動します。

@Override
public function onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    context.getApplicationContext().startService(context.getApplicationContext(), ScreenStateService.class));
}

ウィジェットの終了時には、忘れずにサービスを止めておきます。

@Override
public void onDeleted(Context context, int[] appWidgetIds) {
    context.getApplicationContext().stopService(context.getApplicationContext(), ScreenStateService.class));
    super.onDeleted(context, appWidgetIds);
}

こうしておけば、マニフェストファイルで指定することで jp.bpsinc.android.SCREEN_ON などのイベントを受信できます。

このままだと複数ウィジェットに対応していないので、カウンタ方式などでもう少し工夫した方が良いですが・・・

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。