问题
Problem
I am building an application that requires some of the functionality of the Radar.io SDK, and so I decided to create plugin so after this project is over I can share the plugin with the rest of the Flutter Community. The problem is, I am not able to receive events in this plugin. This is important for the plugin since in order to receive events such as geolocation triggers and other background events this receiver needs to be receiving realtime information.
I have successfully implemented every function in their SDK for Android (using Kotlin) seen here https://radar.io/documentation/sdk, however, the receiver is not getting called when an event takes place. I know the device is being tracked since the location is updated in the Radar.io dashboard, however, the receiver is not executed at all when various events take place.
What I have tried
Here is how the documentation tells you to register the receiver in the Manifest.
<receiver
android:name=".MyRadarReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="io.radar.sdk.RECEIVED" />
</intent-filter>
</receiver>
This would work for a standard application, however, when I register the receiver in the manifest the application does not look in the plugins directory which is where the receiver is located. Instead it looks in the applications android directory and returns an error that the data path could not be found. This causes the application to terminate.
To combat this issue I discovered that the receiver could be set programmatically so I decided to give that a shot.
Inside the Plugin's main Kotlin file I wrote the following lines to be executed in the registerWith
and the onAttachedToEngine
. It is my understanding that these are basically the onStart functions. registerWith
is an older function kept for compatibility with older devices.
val myRadarReceiver = MyRadarReceiver()
val intentFilter = IntentFilter()
intentFilter.addAction("io.radar.sdk.RECEIVED")
ContextWrapper(this.context).registerReceiver(myRadarReceiver, intentFilter)
The class referenced as MyRadarReceiver()
is an extension of the RadarReceiver
class in the SDK which extends BroadcastReceiver
meaning this is my Broadcast Receiver. Here is the class:
public class MyRadarReceiver: RadarReceiver() {
override fun onEventsReceived(context: Context, events: Array<RadarEvent>, user: RadarUser) {
println("test: " + "an event was received")
}
override fun onLocationUpdated(context: Context, location: Location, user: RadarUser) {
println("test: " + "location was updated")
}
override fun onClientLocationUpdated(context: Context, location: Location, stopped: Boolean, source: Radar.RadarLocationSource) {
println("test: " + "client location updated")
}
override fun onError(context: Context, status: Radar.RadarStatus) {
println("test: " + status)
}
override fun onLog(context: Context, message: String) {
println("test: " + message)
}
}
When I started background tracking on the emulated device I expected one of the functions in MyRadarReceiver
to execute, but nothing was printed to the terminal. There was no errors, but nothing was received. This makes me wonder if I set the intent incorrectly or if maybe the Receiver was written improperly. I don't know another way to set the intent so I decided to rewrite the MyRadarReceiver in a simpler form like so:
public class MyRadarReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
println("works! Something was received")
}
}
Unfortunately nothing was printed to the console so I now believe it has something to do with my intent.
Summary
The only solution I have left to try is to write the receiver in the application instead of in the plugin. This may work, however, I was hoping to share this plugin with the Flutter community when I was finished. Radar is a very powerful platform and bringing this plugin to the Flutter community could have an outstanding impact.
回答1:
Solution
After seeing the comment by Nitrodon I took a different look at the problem and found a solution. I am not sure why the programmatic Receiver initialization didn't work, however, here is what I put in my plugin's Android Manifest.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.youorganization.yourproject">
<application
android:name="io.flutter.app.FlutterApplication">
<receiver
android:name=".MyRadarReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="io.radar.sdk.RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
You cannot add an android label or anything else to the application tags or it will throw an error out of conflict with the application's Android Manifest. For this reason, you just need to declare the receiver in the simple application tags that only contain the name which is io.flutter.app.FlutterApplication
. I hope this helps someone else! If anyone has anything to add please do but it finally works!
来源:https://stackoverflow.com/questions/64052156/how-do-you-use-receiver-broadcastreceiver-in-a-flutter-plugin