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 などのイベントを受信できます。
このままだと複数ウィジェットに対応していないので、カウンタ方式などでもう少し工夫した方が良いですが・・・