Flutter EventChannel无法向Dart端传输安卓分享数据问题
问题:Android分享数据无法通过EventChannel传递到Flutter端
已成功将应用加入安卓分享面板,原生侧能正常捕获分享的文本或图片Uri(日志可查),但EventChannel始终无法把数据传到Dart端。MainActivity和AndroidManifest配置已完成,相关代码如下:
MainActivity代码
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") } } }
AndroidManifest配置
<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>
Dart代码
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; }); }......
解决方案
核心问题点
- EventChannel初始化时机不对:
onCreate调用onSharedIntent时,Flutter Engine还没完成初始化(configureFlutterEngine在onCreate之后执行),此时设置的StreamHandler无法被Dart端监听。 - Uri无法直接传递:原生Uri对象不能直接通过EventChannel序列化传给Dart,必须转成字符串。
- Dart端未正确订阅流:
map只是数据转换操作,不会触发流订阅,必须调用listen才能生效。
修复步骤
1. 调整原生侧代码逻辑
把EventChannel的配置移到configureFlutterEngine中,先缓存分享数据,等Engine初始化完成后再传递:
class MainActivity: FlutterActivity() { private var sharedData: Any? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.i("TAG123","onCreate") // 先缓存分享数据 sharedData = getSharedContent() } override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) Log.i("TAG123","configure flutter engine") // 初始化EventChannel并设置StreamHandler EventChannel(flutterEngine.dartExecutor.binaryMessenger, "sharePlatform") .setStreamHandler(object : EventChannel.StreamHandler { override fun onListen(arguments: Any?, events: EventSink) { Log.e("TAG123", "onListen triggered") sharedData?.let { data -> // Uri转字符串传递 val sendData = if (data is Uri) data.toString() else data events.success(sendData) } ?: events.error("NO_DATA", "无分享数据", null) } override fun onCancel(arguments: Any?) { Log.e("TAG123", "onCancel triggered") } }) } // 提取分享数据的独立方法 private fun getSharedContent(): Any? { val receivedAction = intent.action val receivedType = intent.type if (receivedAction == Intent.ACTION_SEND) { return when { receivedType?.startsWith("text/") == true -> { intent.getStringExtra(Intent.EXTRA_TEXT)?.also { Log.e("TAG123", "收到文本: $it") } } receivedType?.startsWith("image/") == true -> { 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? } receiveUri?.also { Log.e("TAG123", "收到图片Uri: $it") } } else -> null } } Log.e("TAG123", "无分享内容") return null } // 处理应用后台唤起的情况 override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) this.intent = intent sharedData = getSharedContent() // 重新设置StreamHandler传递新数据 flutterEngine?.let { engine -> EventChannel(engine.dartExecutor.binaryMessenger, "sharePlatform") .setStreamHandler(object : EventChannel.StreamHandler { override fun onListen(arguments: Any?, events: EventSink) { sharedData?.let { data -> val sendData = if (data is Uri) data.toString() else data events.success(sendData) } ?: events.error("NO_DATA", "无分享数据", null) } override fun onCancel(arguments: Any?) {} }) } } }
2. 修复Dart端流订阅
确保调用listen触发订阅,同时添加取消订阅的逻辑避免内存泄漏:
class _MyHomePageState extends State<MyHomePage> { var data = ""; final _eventChannel = const EventChannel('sharePlatform'); StreamSubscription? _dataSubscription; @override void initState() { super.initState(); _startListeningSharedData(); } void _startListeningSharedData() { _dataSubscription = _eventChannel.receiveBroadcastStream() .distinct() .listen((dynamic event) { debugPrint("TAG123Flutter $event"); setState(() { data = event.toString(); }); }, onError: (error) { debugPrint("接收分享数据出错: $error"); }); } @override void dispose() { _dataSubscription?.cancel(); super.dispose(); } // ... 其他页面代码 }
内容的提问来源于stack exchange,提问作者BraveEvidence
相关产品推荐
相关产品推荐

