2

基于复选框首选项,我启用了一堆接收器并向他们广播,以便他们为自己安排一堆警报。 编辑:接收器都设置警报并等待来自 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)
    }
}

问题

  1. 为什么

    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>  
    

    我希望隐式意图传播到注册的接收者 - 为什么我必须使这些隐式意图显式?我希望这很容易回答 - 我只是忽略了/没有在文档中得到一些东西:)

  2. _enableDisableReceivers(ctx, true);在我广播 Intent 之前,我是否需要确保调用实际上会启用接收器?_enableDisableReceivers(ctx, false);同样,在我调用禁用接收器之前,我是否必须等到收到意图?如果是,我应该怎么做?

  3. (我得到的第一个答案是奖励)不能将 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为最终通知。

4

1 回答 1

0

这不是一个答案 - 只是想问一些不适合评论的问题。

你在做什么——只是让一个接收器足够长的时间来发送一个意图——对我来说看起来很不寻常。你确定那是你想做的吗?我习惯于为系统意图启用/禁用接收器,而不是为自定义意图启用/禁用接收器。

关于 Q#2,为什么会出现尝试减少启用接收器的窗口的问题?为什么在发送意图之前不启用接收器,然后在收到意图之后才禁用它?

我假设所有这些都发生在同一个过程中——听起来就是这样。而且,如果是这样的话,为什么还要在清单中声明你的接收者呢?您还可以考虑切换到 LocalBroadcastManager。

编辑:

问题 3。您怀疑无法将 LBM 与警报管理器一起使用。看到这个帖子

于 2013-04-01T01:32:54.750 回答