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