読者です 読者をやめる 読者になる 読者になる

2hours

1日2時間でなにができるかな

ウィジェットでIntentFilterを使う

Android


時計の秒数表示を諦めたことによって、更新処理の変更を行った。


WidgetProviderでIntentFilterをセットすると

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_TIME_TICK);
    context.registerReceiver(mIntentReceiver, filter, null , mHandler);
}
という感じでWidgetProviderのonUpdateでIntentFilterをセットすると。
Caused by: android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents
登録出来ないと怒られてしまう。


http://feather.cocolog-nifty.com/weblog/2009/11/androidaction_t.html
調べていたら、こちらの方も「うまく行かなかった」と書いていた。


色々試してみた結果

どうもWidgetProviderのcontextに対してIntentFilterをセットするとダメなようだったので、
WidgetConfigureでセットするようにしたら、うまく動くようになった。


WidgetConfigure
public void onClick(View v) {
    〜(略)〜
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_TIME_TICK);
    this.getApplicationContext().registerReceiver(WidgetProvider.getIntentReceiver(), filter, null, mHandler);
    〜(略)〜
}
設定画面の決定ボタンが押されたらIntent.ACTION_TIME_TICKを登録。

WidgetProvider
public static BroadcastReceiver getIntentReceiver() {
    return mIntentReceiver;
}

private final static BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        〜(更新処理)〜
    }
};
WidgetProviderにBroadcastReceiverを定義しておいて、更新処理を行う。
WidgetConfigureでこいつを使うためにgetterも用意。


これでウィジェットでもIntent.ACTION_TIME_TICKを使った更新処理が出来た。



果たしてこれが一般的なやり方かどうかは定かではないが・・・。