I am trying to show my app in share sheet of android and I was able to successfully do it but I am not able to send data from native side to dart using EventChannel
.
I have updated my MainActivity to following
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i("TAG123","onCreate")
onSharedIntent()
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
Log.i("TAG123","configure flutter engine")
}
private fun onSharedIntent() {
val receivedAction: String? = intent.action
val receivedType: String? = intent.type
if (receivedAction == Intent.ACTION_SEND) {
// check mime type
if (receivedType?.startsWith("text/") == true) {
val receivedText: String? = intent.getStringExtra(Intent.EXTRA_TEXT)
if (receivedText != null) {
//do your stuff
Log.e("TAG123", receivedText.toString())
if(flutterEngine?.dartExecutor?.binaryMessenger != null){
Log.i("TAG123","flutter engine not null")
}
Log.e("TAG123", "here")
EventChannel(
flutterEngine!!.dartExecutor.binaryMessenger,
"sharePlatform"
).setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any, events: EventSink) {
Log.e("TAG123", "here123")
events.success(receivedText)
}
override fun onCancel(arguments: Any) {
Log.e("TAG123", "here123456")
}
})
} else {
Log.e("TAG123", "no data")
}
} else if (receivedType?.startsWith("image/") == true) {
// val receiveUri: Uri? = intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri?
val receiveUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
} else {
intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri?
}
if (receiveUri != null) {
Log.e("TAG123", receiveUri.toString())
if(flutterEngine?.dartExecutor?.binaryMessenger != null){
Log.i("TAG123","flutter engine not null")
}
EventChannel(
flutterEngine!!.dartExecutor.binaryMessenger,
"sharePlatform"
).setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any, events: EventSink) {
Log.e("TAG123", "here123")
events.success(receiveUri)
}
override fun onCancel(arguments: Any) {
Log.e("TAG123", "here123456")
}
})
} else {
Log.e("TAG123", "no image data")
}
}
} else if (receivedAction == Intent.ACTION_MAIN) {
Log.e("TAG123", "onSharedIntent: nothing shared")
}
}
}
I have made the required changes to AndroidManifest
as well
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="text/*" />
</intent-filter>
I can see the url or uri of image when I share it from some other app to my app in logs but EventChannel
never works
Below is my dart code
class _MyHomePageState extends State<MyHomePage> {
var data = "";
final _eventChannel = const EventChannel('sharePlatform');
@override
void initState() {
super.initState();
_eventChannel.receiveBroadcastStream().distinct().map((dynamic event) {
debugPrint("TAG123Flutter $event");
setState(() {
data = event;
});
// return event;
});
}......
4
Answers
This is because you didn’t subscribe to the stream. You are operating on the stream only at the moment MyHomePage is initialized. If you’re not familiar with the topic, I suggest studying event driven programming more, it’s confusing in Dart to read write visualize it.
This way the widget will listen to events that come as long as it is alive.
If you want to use
distinct
, you can use a StreamTransformer. For example,I think the reason is because of
Why do you need to use
flutterEngine!!.dartExecutor.binaryMessenger
?in Flutter you create EventChannel like this
EventChannel('sharePlatform')
So I think in ADR code you should use the default executor as messager
like this:
EventChannel(flutterEngine!!.dartExecutor, "sharePlatform")
Hope it helps.
You are calling
onSharedIntent
method insideonCreate
method directly.Looks like that can be the issue because
onSharedIntent
won’t be invoked in this case. You should wrap theonSharedIntent
inside aHandler
like this:Try this. This should work.
There doesn’t seem any obvious reason. But you can also try to make the streamHandler another class rather than an object type. Just try it as a hack as you said the problem seems to be in the eventChannel invocation.
Do this:
Then call:
I went through this blog to resolve your issue and came upon with the following solution.
Replace your MainActivity Code with the following
Replace your dart code with the following
Hope this helps.
Thanks 🙂