Code spécifique à la plateforme Flutter

Cette section présentera comment utiliser les canaux de plateforme pour appeler du code natif de plateforme dans Flutter.


Aperçu des canaux de plateforme

Les canaux de plateforme permettent au code Dart de communiquer avec les plateformes natives (iOS/Android).

TypeDescription
MethodChannelCanaux de méthode, utilisés pour appeler des méthodes de plateforme
EventChannelCanaux d'événements, utilisés pour le streaming de données

Appel côté Dart

Exemple : utilisation de MethodChannel

import 'package:flutter/services.dart';

// Définir le canal
class PlatformChannel {
  static const MethodChannel _channel = MethodChannel('my_app/channel');

  // Appeler la méthode native - obtenir le niveau de batterie
  static Future<int> getBatteryLevel() async {
    try {
      final int batteryLevel = await _channel.invokeMethod('getBatteryLevel');
      return batteryLevel;
    } on PlatformException catch (e) {
      print('Impossible d'obtenir le niveau de batterie : ${e.message}');
      return -1;
    }
  }

  // Appeler la méthode native - afficher un Toast
  static Future<void> showToast(String message) async {
    try {
      await _channel.invokeMethod('showToast', {'message': message});
    } on PlatformException catch (e) {
      print('Échec de l’affichage du Toast : ${e.message}');
    }
  }

  // Appeler la méthode native - obtenir les informations de l’appareil
  static Future<Map<String, dynamic>> getDeviceInfo() async {
    try {
      final result = await _channel.invokeMapMethod('getDeviceInfo');
      return result ?? {};
    } on PlatformException catch (e) {
      print(Échec de l’obtention des informations de l’appareil : ${e.message});
      return {};
    }
  }
}

// Exemple d'utilisation
class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () async {
        final battery = await PlatformChannel.getBatteryLevel();
        print(Niveau de la batterie : $battery%);
      },
      child: const Text(Obtenir le niveau de la batterie),
    );
  }
}

Implémentation Android (Kotlin)

Exemple : code côté Android

// MainActivity.kt
package com.example.my_app

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

class MainActivity : FlutterActivity() {
    private val CHANNEL = "my_app/channel"

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

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "getBatteryLevel" -> {
                        val batteryLevel = getBatteryLevel()
                        if (batteryLevel != -1) {
                            result.success(batteryLevel)
                        } else {
result.error("UNAVAILABLE", "Impossible d'obtenir le niveau de la batterie", null)
                        }
                    }
                    "showToast" -> {
                        val message = call.argument<String>("message")
                        showToast(message!!)
                        result.success(null)
                    }
                    else -> {
                        result.notImplemented()
                    }
                }
            }
    }

    private fun getBatteryLevel(): Int {
        return try {
            val batteryManager = getSystemService(BATTERY_SERVICE) as BatteryManager
            batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
        } catch (e: Exception) {
            -1
        }
    }

    private fun showToast(message: String) {
        android.widget.Toast.makeText(this, message, android.widget.Toast.LENGTH_SHORT).show()
    }
}

Implémentation iOS (Swift)

Exemple : code côté iOS

// AppDelegate.swift
import Flutter
import UIKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private let CHANNEL = "my_app/channel"

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController

        let channel = FlutterMethodChannel(
            name: CHANNEL,
            binaryMessenger: controller.binaryMessenger
        )

        channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
            switch call.method {
            case "getBatteryLevel":
                self.getBatteryLevel(result: result)
            case "showToast":
                if let args = call.arguments as? [String: Any],
                   let message = args["message"] as? String {
                    self.showToast(message: message)
                    result(nil)
                }
            default:
                result(FlutterMethodNotImplemented)
            }
        }

        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    private func getBatteryLevel(result: @escaping FlutterResult) {
        UIDevice.current.isBatteryMonitoringEnabled = true
        let batteryLevel = UIDevice.current.batteryLevel

        if batteryLevel < 0 {
result(FlutterError(code: "UNAVAILABLE", message: "Impossible d'obtenir le niveau de la batterie", details: nil))
        } else {
            result(Int(batteryLevel * 100))
        }
    }

    private func showToast(message: String) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        present(alert, animated: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            alert.dismiss(animated: true)
        }
    }
}

Les canaux de plateforme sont le principal moyen pour Flutter de communiquer avec du code natif, couramment utilisés pour appeler des API système, des fonctionnalités matérielles ou utiliser des SDK natifs tiers.

autres extensions