ホームスクリーンウィジェット(AppWidget)開発では、省エネ対策が重要になります。
画面がOFFの時は、無駄な処理を省きたいものです。
リファレンスによると
・ACTION_SCREEN_ON : "android.intent.action.SCREEN_ON"
・ACTION_SCREEN_OFF : "android.intent.action.SCREEN_OFF"
というのが定義されているので、これを受信すれば対策できそうです。
http://developer.android.com/reference/android/content/Intent.html
しかし、単にmanifest.xmlのreceiverに書いても、受信してくれません。
ダメな例:
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name="jp.bpsinc.android.test.WidgetProvider">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/provider" />
</receiver>
</application></pre>
SCREEN_ONなどを受け取るには、アプリの初期化処理で、コードから登録する必要があります。
<pre class="brush:java">@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
context.getApplicationContext().registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "RECEIVE");
}
}, filter);
}
この際、
・渡されたcontextではなくApplicationContextを使うこと
・AppWidgetProviderもonReceive持っているからいけそうな気がするが、receiverにthisを指定してはいけない
がポイントです。
守らないと、以下のようなエラーが発生します。
android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents
Providerにまとめて処理させたいなら、以下のようにやればOKです。
public class WidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
context.getApplicationContext().registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
WidgetProvider.this.onReceive(context, intent);
}
}, filter);
}
@Override
public void onReceive(Context context, Intent intent) {
//なんたらかんたら
}
}
ただ、単にこの方法を使うと、Receiverが無限に増えていってしまいます。
アプリを終了してもReceiverが残ってしまうので、サービスにbindしないと実質的にはダメですね。