How to call platform specific code in flutter

Writing Android Specific Code

In Flutter, writing Android-specific code involves using platform channels to communicate between Dart and native Android (Java/Kotlin) code. This is useful when you need to access Android-specific features that are not available directly through Flutter's SDK.

Step 1: Create a Platform Channel

A platform channel is a communication bridge between Dart and native Android code.

  • Set up the channel in Dart code: Use theMethodChannel class to communicate with the Android native side.


import 'package:flutter/services.dart';

class AndroidSpecificCode {
  static const MethodChannel _channel = MethodChannel('com.example.android_specific_code');

  static Future<String> getAndroidVersion() async {
    try {
      final String version = await _channel.invokeMethod('getAndroidVersion');
      return version;
    } on PlatformException catch (e) {
      return "Failed to get Android version: '${e.message}'.";
    }
  }
}

  1. Channel name:com.example.android_specific_code (must match between Dart and Android).

Step 2: Implement Native Android Code

  1. Open the Android project in your Flutter app. Navigate toandroid/app/src/main/java/.../MainActivity.java or .kt.
  2. Modify the MainActivity:Add a method call handler to listen for messages from the Dart side.


package com.example.android_specific_code

import android.os.Build
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.android_specific_code"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getAndroidVersion") {
                val androidVersion = "Android ${Build.VERSION.RELEASE}"
                result.success(androidVersion)
            } else {
                result.notImplemented()
            }
        }
    }
}

Step 3: Use the Platform Channel in Flutter

Call the platform-specific method in Dart.


import 'package:flutter/material.dart';
import 'android_specific_code.dart'; // Import the class with platform channel logic

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Android-Specific Code")),
        body: Center(
          child: FutureBuilder<String>(
            future: AndroidSpecificCode.getAndroidVersion(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text("Error: ${snapshot.error}");
              } else {
                return Text("Android Version: ${snapshot.data}");
              }
            },
          ),
        ),
      ),
    );
  }
}

Step 4: Test the App

  1. Run the app on an Android emulator or device.
  2. You should see the Android version displayed in the app.

main.dart


import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';

void main() => runApp(DeviceApp());

class DeviceApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Browser Opener',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: HomePage(
        pageTitle: 'Flutter Browser Opener',
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  HomePage({Key? key, required this.pageTitle}) : super(key: key);

  final String pageTitle;
  static const platform = MethodChannel('com.deviceapp.flutter/browser');

  Future<void> _launchBrowser() async {
    try {
      final int result = await platform.invokeMethod('launchBrowser', Map<String, String>{
        'url': 'https://www.google.com',
      });
    } on PlatformException catch (e) {
      print("Error: Unable to open browser. ${e.message}");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(pageTitle),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Open Browser'),
          onPressed: _launchBrowser,
        ),
      ),
    );
  }
}

MainActivity.java


package com.deviceapp.flutter;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "com.deviceapp.flutter/browser";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);

        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
            new MethodChannel.MethodCallHandler() {
                @Override
                public void onMethodCall(MethodCall call, MethodChannel.Result result) {
                    String url = call.argument("url");
                    if (call.method.equals("launchBrowser")) {
                        openBrowser(call, result, url);
                    } else {
                        result.notImplemented();
                    }
                }
            }
        );
    }

    private void openBrowser(MethodCall call, MethodChannel.Result result, String url) {
        Activity activity = this;
        if (activity == null) {
            result.error("ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without a foreground activity", null);
            return;
        }

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse(url));

        activity.startActivity(intent);
        result.success(true);
    }
}
Previous Post Next Post