This should be obvious but I can't find the solution. Many people have asked it and the reply is usually to just switch to a context-registered receiver instead. I have an accessibility service which needs to be notified when the Manifest-declared receiver picks up something. Obviously this can't be done with an interface since I can't find a way to get the instance of the receiver. Here's some code:
Manifest:
<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>
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;
}
}
CodePudding user response:
I asked a couple of times for concrete scenarios, and you did not really provide any, so I am going to answer with an abstract scenario: suppose that your broadcast is designed to send a command to the service.
In that case, you could:
Implement a singleton (here called
CommandBus, for lack of a better idea of a name). Ideally, that singleton would be set up by a dependency inversion framework (e.g., Dagger/Hilt).Have
CommandBusexpose some reactive way to get commands to the service. If you were using Kotlin, that could be aSharedFlow. Since you are using Java, that could be an RxJavaObservable, or perhaps a simple callback.Have
MyAccessibilityServiceget access to theCommandBussingleton and use whatever you set up in step #2 to find out about commands.Have
CommandBusexpose an API to hand it commands to deliver to the service (e.g., asendCommand()method).Have
MyBroadcastReceiverget access to theCommandBussingleton and call the method from step #4 inonReceive().
At this point, when MyBroadcastReceiver receives a broadcast, it tells CommandBus to send the command, which then flows over to MyAccessibilityService, which goes and does something.
