如何让清单声明的广播接收器与 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;
}
}
我问了几次具体的场景,你没有真正提供任何,所以我将用一个抽象的场景来回答:假设你的广播是为了向服务发送命令。
在这种情况下,您可以:
实现单例(这里称为 CommandBus
,因为没有更好的名字)。理想情况下,该单例将由依赖倒置框架(例如,Dagger/Hilt)设置。
CommandBus
公开一些响应式方法来获取服务命令。如果您使用的是 Kotlin,那可能是 SharedFlow
。由于您使用的是 Java,这可能是一个 RxJava Observable
,或者可能是一个简单的回调。
让 MyAccessibilityService
访问 CommandBus
单例并使用您在步骤 #2 中设置的任何内容来查找命令。
让 CommandBus
公开一个 API 以将命令传递给服务(例如,sendCommand()
方法)。
让 MyBroadcastReceiver
访问 CommandBus
单例并调用 onReceive()
.
中第 4 步的方法
此时,当MyBroadcastReceiver
接收到广播时,它告诉CommandBus
发送命令,然后流向MyAccessibilityService
,它会做一些事情。
这应该很明显,但我找不到解决方案。很多人都问过,答案通常是切换到上下文注册的接收器。我有一个无障碍服务,当清单声明的接收者拿起东西时需要通知它。显然这不能通过接口来完成,因为我找不到获取接收器实例的方法。这是一些代码:
清单:
<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;
}
}
我问了几次具体的场景,你没有真正提供任何,所以我将用一个抽象的场景来回答:假设你的广播是为了向服务发送命令。
在这种情况下,您可以:
实现单例(这里称为
CommandBus
,因为没有更好的名字)。理想情况下,该单例将由依赖倒置框架(例如,Dagger/Hilt)设置。CommandBus
公开一些响应式方法来获取服务命令。如果您使用的是 Kotlin,那可能是SharedFlow
。由于您使用的是 Java,这可能是一个 RxJavaObservable
,或者可能是一个简单的回调。让
MyAccessibilityService
访问CommandBus
单例并使用您在步骤 #2 中设置的任何内容来查找命令。让
CommandBus
公开一个 API 以将命令传递给服务(例如,sendCommand()
方法)。让
中第 4 步的方法MyBroadcastReceiver
访问CommandBus
单例并调用onReceive()
.
此时,当MyBroadcastReceiver
接收到广播时,它告诉CommandBus
发送命令,然后流向MyAccessibilityService
,它会做一些事情。