skip to Main Content

I am trying to integrate native android code in my flutter app. I have service class which get user’s location. Now this location update will be continuous and the location will be send from my service class to MainActivity via callback method called onLocationUpdated

Now in my MainActivity.kt

class MainActivity : FlutterFragmentActivity(),LocationCallback {
   private val networkEventChannel = "com.example.locationconnectivity"
    private var attachEvent: EventChannel.EventSink? = null

   override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
       

        EventChannel(
            flutterEngine.dartExecutor.binaryMessenger,
            networkEventChannel
        ).setStreamHandler(
            object : EventChannel.StreamHandler {
                override fun onListen(args: Any, events: EventChannel.EventSink) {
                    Log.w("TAG_NAME", "Adding listener")
                    attachEvent = events


                }

                override fun onCancel(args: Any) {
                    Log.w("TAG_NAME", "Cancelling listener")
                    attachEvent = null
                    println("StreamHandler - onCanceled: ")
                }
            }
        )
      .....
}

 override fun onLocationUpdated(latitude: Double, longitude: Double) {
        runOnUiThread {
            Log.i("attacheventis", "${attachEvent}",)
            Toast.makeText(this, "Lat lng ${latitude} ${longitude}", Toast.LENGTH_SHORT).show()

                    attachEvent?.success("${latitude} ${longitude}")

        }
    }
}

Now when I call attachEvent?.success in onLocationUpdated I always get attachEvent as null and onListen and onCancel are never called in configureFlutterEngine

Also I don’t want to create separate class for EventChannel. Need to handle everything in MainActivity

2

Answers


  1. Chosen as BEST ANSWER

    This is insane. The error was because I forgot to add ? to args: Any in my kotlin code. Something like below

    override fun onListen(args: Any?, events: EventChannel.EventSink) {
    

  2. The onListen callback in your Android MainActivity is called when the Flutter side starts listening to the event stream. Similarly, onCancel is called when Flutter stops listening to the event stream. If neither of these methods is being called, it is likely because there is no Flutter code that is attempting to listen to or cancel the stream.
    See also "Event Channel in Flutter" from Rishabh Sharma.

    On the Flutter side, you will need to use the EventChannel to listen to the events emitted by the Android side.

    Create (in your Flutter widget with Dart) an instance of the EventChannel with the same name as you defined in the Android side, and listen to the stream of events:

    const eventChannel = EventChannel('com.example.locationconnectivity');
    
    StreamSubscription? subscription;
    
    @override
    void initState() {
      super.initState();
    
      subscription = eventChannel.receiveBroadcastStream().listen(
        (dynamic event) {
          print('Received: $event');
          // Handle the received location here
        },
        onError: (dynamic error) {
          print('Received error: ${error.message}');
        },
      );
    }
    
    @override
    void dispose() {
      subscription?.cancel();
      super.dispose();
    }
    

    That code on the Flutter/Dart side would be enough for your code on the Android side to have a non-null EventChannel.EventSink.


    from your code, if you do not see the Kotlin android/app/src/main/kotlin/com/example/flutapp/MainActivity.kt "Adding listener" log trace, it suggests that the Dart side is not initiating the connection to the EventChannel properly, or the bridge between Flutter’s Dart code and native code has some issue.

    First, make sure the Dart side logic is being executed. Add a print statement right before you start listening to the EventChannel in your lib/main.dart.

    @override
    void initState() {
        super.initState();
        print("Dart side: Initializing EventChannel listener...");
        
        subscription = _eventChannel.receiveBroadcastStream().listen(
        (dynamic event) {
            print('FlutterReceived: $event');
        },
        onError: (dynamic error) {
            print('Received error: ${error.message}');
        },
        );
    }
    

    You can also try, just to get more detail from any error:

        onError: (Object obj, StackTrace stackTrace) {
          print(obj);
          print(stackTrace);
        },
    

    Check your Flutter logs (via the terminal or console where you run your Flutter app) to make sure this print statement is being executed.
    And do so after a full stop/retart of the application: no hot-reload.
    And preferably a full rebuild first (flutter clean + flutter run)

    Run flutter doctor to check if there are any issues with your Flutter setup.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search