DEV Community

Omar Elsadany
Omar Elsadany

Posted on

🔌 Native Channels in Flutter — A Complete Guide

When building Flutter apps, sometimes Dart alone isn’t enough. You may need native functionality—like accessing sensors, battery info, Bluetooth, or a custom SDK.

That’s where Platform Channels (a.k.a. Native Channels) come in. They allow Flutter to communicate with the host platform (Android/iOS, desktop, etc.) and execute native code seamlessly.


🏗 What Are Platform Channels?

Flutter runs on its own engine with Dart, but you can bridge to the host platform when needed.

Platform channels send asynchronous messages between:

  • Flutter (Dart side)
  • Host platform (Kotlin/Java for Android, Swift/Objective-C for iOS, etc.)

👉 Think of it as a two-way communication bridge.


⚡ Types of Platform Channels

Flutter provides three types of channels:


1. MethodChannel

Best for one-time operations.

  • Purpose: Invoke a native method and get a response back.
  • Pattern: Request → Response (like a function call).

Use Cases:

  • Fetching device info (battery, OS version, etc.)
  • Triggering a single action (open camera, share a file)

2. EventChannel

Best for continuous streams of data.

  • Purpose: Subscribe once and keep receiving updates.
  • Pattern: Stream of events over time.

Use Cases:

  • Sensors (accelerometer, gyroscope, pedometer)
  • System updates (battery state, connectivity changes)

3. BasicMessageChannel

Best for flexible, bi-directional messaging.

  • Purpose: Send raw, asynchronous messages (text, JSON, binary) back and forth.
  • Pattern: Free-form communication (no fixed method names).

Use Cases:

  • Continuous two-way messaging
  • Custom protocols (status updates, commands)

💻 Platforms & Native Languages

Flutter supports multiple platforms and integrates with their native languages:

  • Android → Kotlin, Java
  • iOS → Swift, Objective-C
  • Windows → C++
  • macOS → Objective-C
  • Linux → C

🧑‍💻 Code Examples

Example 1: Get Battery Level (MethodChannel)

Use case: Flutter asks Android for current battery percentage.

// Flutter side
static const platform = MethodChannel('battery');

Future<void> getBatteryLevel() async {
  final int level = await platform.invokeMethod('getBatteryLevel');
  print("Battery level: $level%");
}
Enter fullscreen mode Exit fullscreen mode
// Android side (Kotlin)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "battery")
  .setMethodCallHandler { call, result ->
    if (call.method == "getBatteryLevel") {
      val batteryLevel = getBatteryPercentage()
      result.success(batteryLevel)
    }
  }
Enter fullscreen mode Exit fullscreen mode

Example 2: Steps Counter (EventChannel)

Use case: Count user steps while moving.

  • EventChannel → Stream real-time step counts.
// Flutter side
static const eventChannel = EventChannel('stepCountStream');

void listenSteps() {
  eventChannel.receiveBroadcastStream().listen((event) {
    print("Steps: $event");
  }, onError: (error) {
    print("Error: $error");
  });
}
Enter fullscreen mode Exit fullscreen mode
// Android side (Kotlin)
EventChannel(flutterEngine.dartExecutor.binaryMessenger, "stepCountStream")
  .setStreamHandler(object : EventChannel.StreamHandler {
    override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
        // Example: simulate step counter
        events.success(100) // Replace with real step counter data
    }

    override fun onCancel(arguments: Any?) {
        // Stop sending events when cancelled
    }
  })
Enter fullscreen mode Exit fullscreen mode

Example 3: Live Chat / Messaging (BasicMessageChannel)

Use case: Exchange chat messages between Flutter UI and a native chat engine.

static const messageChannel =
    BasicMessageChannel<String>('chat', StringCodec());

void sendMessage(String msg) {
  messageChannel.send(msg);
}

void listenMessages() {
  messageChannel.setMessageHandler((msg) async {
    print("New message: $msg");
  });
}
Enter fullscreen mode Exit fullscreen mode

🚀 Final Thoughts

  • MethodChannel → One-time calls.
  • EventChannel → Continuous updates.
  • BasicMessageChannel → Free-form, two-way messaging.

📁 GitHub Projects

Repository: https://github.com/AhmedTarek-f/native-channel-app.git

Complete Flutter app demonstrating all three platform channel types:

🔋 Battery Level (MethodChannel)

  • Get device battery percentage on button tap
  • Simple request → response pattern

💬 Live Chat (BasicMessageChannel)

  • Real-time bidirectional messaging
  • Send and receive messages between Flutter and native

👟 Step Counter (MethodChannel + EventChannel)

  • MethodChannel: Start/stop step counting service
  • EventChannel: Stream real-time step updates
  • Background service with sensor integration

🚀 Quick Start

git clone https://github.com/AhmedTarek-f/native-channel-app.git
cd native-channel-app
flutter pub get
flutter run
Enter fullscreen mode Exit fullscreen mode

Features: All 3 channel types • Foreground services • Sensor integration • Permission handling • BLoC state management

Top comments (0)