如何让清单声明的广播接收器与 activity 或服务通信?

How to have a Manifest-declared broadcast receiver communicate with an activity or service?

这应该很明显,但我找不到解决方案。很多人都问过,答案通常是切换到上下文注册的接收器。我有一个无障碍服务,当清单声明的接收者拿起东西时需要通知它。显然这不能通过接口来完成,因为我找不到获取接收器实例的方法。这是一些代码:

清单:

<service
    android:name=".MyAccessibilityService"
    android:exported="true"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:process=":listenerProcess4">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>

    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibilityservice" />
</service>

<receiver
    android:name=".MyBroadcastReceiver"
    android:exported="false"
    android:process=":listenerProcess4">
    <intent-filter>
        <action android:name="roastie_toastie" />
    </intent-filter>
</receiver>

接收器:

public class MyBroadcastReceiver extends BroadcastReceiver {
    BroadcastReceivedListener mBroadcastReceivedListener;

    public void setBroadcastReceivedListener(BroadcastReceivedListener broadcastReceivedListener) {
        mBroadcastReceivedListener = broadcastReceivedListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        mBroadcastReceivedListener.broadcastReceived();
    }

    public interface BroadcastReceivedListener {
        void broadcastReceived();
    }
}

MyAccessibilityService:

public class MyAccessibilityService extends AccessibilityService implements MyBroadcastReceiver.BroadcastReceivedListener {

    boolean lightsAreOn = true;

    @Override
    public void broadcastReceived() {
        lightsAreOn = false;
    }
}

我问了几次具体的场景,你没有真正提供任何,所以我将用一个抽象的场景来回答:假设你的广播是为了向服务发送命令。

在这种情况下,您可以:

  1. 实现单例(这里称为 CommandBus,因为没有更好的名字)。理想情况下,该单例将由依赖倒置框架(例如,Dagger/Hilt)设置。

  2. CommandBus 公开一些响应式方法来获取服务命令。如果您使用的是 Kotlin,那可能是 SharedFlow。由于您使用的是 Java,这可能是一个 RxJava Observable,或者可能是一个简单的回调。

  3. MyAccessibilityService 访问 CommandBus 单例并使用您在步骤 #2 中设置的任何内容来查找命令。

  4. CommandBus 公开一个 API 以将命令传递给服务(例如,sendCommand() 方法)。

  5. MyBroadcastReceiver 访问 CommandBus 单例并调用 onReceive().

    中第 4 步的方法

此时,当MyBroadcastReceiver接收到广播时,它告诉CommandBus发送命令,然后流向MyAccessibilityService,它会做一些事情。