Flutter can absolutely talk to Java code—that’s how you access Android native features. The key concept you need is Platform Channels.

I’ll walk you through it step-by-step, from idea → code → common use cases.


Big picture (how Flutter talks to Java)

Flutter (Dart)
   ↓ Platform Channel
Android (Java)

Flutter sends a message → Java handles it → Java sends a result back.


Method 1: Using Platform Channels (Most Common & Recommended)

Step 1: Create a MethodChannel in Flutter (Dart)

import 'package:flutter/services.dart';

class NativeService {
  static const platform = MethodChannel('com.example/native');

  static Future<String> getDeviceName() async {
    try {
      final String result = await platform.invokeMethod('getDeviceName');
      return result;
    } catch (e) {
      return "Failed to get device name";
    }
  }
}

Usage in UI:

TextButton(
  onPressed: () async {
    String name = await NativeService.getDeviceName();
    print(name);
  },
  child: Text("Get Device Name"),
)

Step 2: Handle the call in Java (Android side)

Open:

android/app/src/main/java/.../MainActivity.java
package com.example.myapp;

import android.os.Build;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "com.example/native";

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        new MethodChannel(
                flutterEngine.getDartExecutor().getBinaryMessenger(),
                CHANNEL
        ).setMethodCallHandler(
            (call, result) -> {
                if (call.method.equals("getDeviceName")) {
                    String deviceName = Build.MODEL;
                    result.success(deviceName);
                } else {
                    result.notImplemented();
                }
            }
        );
    }
}

Now Flutter ↔ Java communication works 🎉


Method 2: Passing Data (Arguments) from Flutter to Java

Flutter

await platform.invokeMethod(
  'addNumbers',
  {"a": 5, "b": 10},
);

Java

if (call.method.equals("addNumbers")) {
    int a = call.argument("a");
    int b = call.argument("b");
    result.success(a + b);
}

Method 3: Calling Java Code Continuously (EventChannel)

Use this when Java sends stream data (battery, sensors, GPS).

EventChannel('com.example/events')

This is useful for:

  • Battery level updates
  • Sensors
  • Network state changes

Method 4: Write a Flutter Plugin (Clean Architecture)

If:

  • You reuse Java code in many apps
  • You want clean separation
  • You’re building production-grade features

Create plugin:

flutter create --template=plugin my_native_plugin

This is how big plugins like camera, firebase, etc. are built.


When should you use Java with Flutter?

✅ Use Java when:

  • You need Android-only APIs
  • Flutter plugin doesn’t exist
  • Performance-critical native code
  • Existing Java SDK integration

❌ Avoid when:

  • Pure UI logic
  • Can be done in Dart easily

Common Real-World Examples

  • Payment SDK (Razorpay, Paytm)
  • Biometric authentication
  • SIM / device info
  • Background services
  • Bluetooth / NFC

Quick comparison

TaskBest Approach
Call Java onceMethodChannel
Stream dataEventChannel
Reusable native featureFlutter Plugin

Categories: Flutter

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *