基于复选框首选项,我启用了一堆接收器并向他们广播,以便他们为自己安排一堆警报。 编辑:接收器都设置警报并等待来自 AlarmManager 的广播(从onReceive
发布的内容中可以清楚地看出)。
设置活动
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue instanceof Boolean) {
boolean enable = (Boolean) newValue;
Monitor.enableMonitoring(getApplicationContext(), enable);
return true;
}
return false;
}
Monitor.enableMonitoring
public static void enableMonitoring(Context ctx, boolean enable) {
Resources resources = ctx.getResources();
CharSequence ac_setup_alarm = resources
.getText(R.string.intent_action_setup_alarm);
CharSequence ac_cancel_alarm = resources
.getText(R.string.intent_action_cancel_alarm);
// if only I could do the above in a static way someclass once and for all
Intent i = new Intent("" + (enable ? ac_setup_alarm : ac_cancel_alarm));
if (enable) {
Log.d(_tag, "enable receivers / setup alarms int : " + i);
_enableDisableReceivers(ctx, enable); // enable == true
ctx.sendBroadcast(i);
} else {
Log.d(_tag, "cancel alarms / disable receivers int : " + i);
ctx.sendBroadcast(i);
_enableDisableReceivers(ctx, enable); // enable != true (will disable)
}
}
问题
为什么
Intent i = new Intent("" + (enable ? ac_setup_alarm : ac_cancel_alarm));
不会收到Intent i = new Intent("" + (enable ? ac_setup_alarm : ac_cancel_alarm), Uri.EMPTY, ctx, BatteryMonitoringReceiver.class);
会按预期收到吗?
显现 :<receiver android:name="di.k23b.hw3.receivers.BatteryMonitoringReceiver" android:enabled="false" > <intent-filter> <action android:name="@string/intent_action_setup_alarm" /> <action android:name="@string/intent_action_cancel_alarm" /> <action android:name="@string/intent_action_monitor" /> </intent-filter> </receiver>
我希望隐式意图传播到注册的接收者 - 为什么我必须使这些隐式意图显式?我希望这很容易回答 - 我只是忽略了/没有在文档中得到一些东西:)
_enableDisableReceivers(ctx, true);
在我广播 Intent 之前,我是否需要确保调用实际上会启用接收器?_enableDisableReceivers(ctx, false);
同样,在我调用禁用接收器之前,我是否必须等到收到意图?如果是,我应该怎么做?(我得到的第一个答案是奖励)不能将 LocalBroadcastManager 与 AlarmaManager 一起使用- 使用引导接收器?(我觉得不是)
为了完整性:
private static void _enableDisableReceivers(Context ctx, boolean enable) {
Log.d(_tag, "enable/disable receivers");
for (Class<? extends BaseReceiver> receiver : RECEIVERS)
BaseReceiver.enable(ctx, enable, receiver);
}
在哪里 :
public static void enable(Context context, boolean enable,
Class<? extends BaseReceiver> receiver) {
PackageManager pacman = context.getPackageManager();
final ComponentName componentName = new ComponentName(context, receiver);
Log.d(_tag, componentName.toString());
final int state = (enable) ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
pacman.setComponentEnabledSetting(componentName, state,
PackageManager.DONT_KILL_APP);
Log.d(_tag,
"pacman :" + pacman.getComponentEnabledSetting(componentName));
}
对于令人难以置信的完整性(BaseMonitoringReceiver):
@Override
final public void onReceive(Context context, Intent intent) {
// FIXME : possible NPE below ?
final String action = intent.getAction(); // can intent==null ?
Log.w(TAG, "" + action);
resources = context.getResources();
ac_setup_alarm = resources.getText(R.string.intent_action_setup_alarm);
ac_cancel_alarm = resources
.getText(R.string.intent_action_cancel_alarm);
ac_monitor = resources.getText(R.string.intent_action_monitor);
if (ac_setup_alarm.equals(action) || ac_cancel_alarm.equals(action)) {
monitoringIntent = new Intent(context, this.getClass());
monitoringIntent.setPackage(RECEIVERS_PACKAGE_NAME);// TODO: needed?
final boolean enable = ac_setup_alarm.equals(action);
setupAlarm(context, enable);
} else if (ac_monitor.equals(action)) {
// monitoring - got broadcast from ALARM
Class<? extends WakefulIntentService> serviceClass = getService();
WakefulIntentService.sendWakefulWork(context, serviceClass);
} else {
Log.w(TAG, "Received bogus intent : " + intent);
return;
}
}
子类(如BatteryMonitoringReceiver
清单中的)只是覆盖getService()
- 整洁不?通知onReceive
为最终通知。