Search code examples
androidflutterkotlindartshare-extension

Flutter's EventChannel not sending data to dart side


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;
    });
  }......

Solution

  • I went through this blog to resolve your issue and came upon with the following solution.

    Replace your MainActivity Code with the following

    class MainActivity: FlutterActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        Log.i("TAG123","onCreate")
    }
    
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        Log.i("TAG123","configure flutter engine")
        EventChannel(
            flutterEngine.dartExecutor.binaryMessenger,
            "sharePlatform"
        ).setStreamHandler(object : EventChannel.StreamHandler {
    
            override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
                Log.e("TAG123", "configure here123")
                Log.e("TAG123", "$intent")
                onSharedIntent(events)
            }
    
            override fun onCancel(arguments: Any?) {
                Log.e("TAG123", "configure here123456")
            }
        })
    }
    
    private fun onSharedIntent(events: EventChannel.EventSink) {
        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")
                    events.success(receivedText)
                } 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")
                    }
                    events.success(receiveUri.toString())
                } else {
                    Log.e("TAG123", "no image data")
                }
            }
        } else if (receivedAction == Intent.ACTION_MAIN) {
            Log.e("TAG123", "onSharedIntent: nothing shared")
        }
      }
    
    }
    

    Replace your dart code with the following

      @override
      void initState() {
      super.initState();
      _eventChannel.receiveBroadcastStream().listen((dynamic event) {
        debugPrint("TAG123Flutter $event");
        setState(() {
          data = event;
        });
        // return event;
      });
    }
    

    Hope this helps. Thanks :)