iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0
Mobile Development

畢業專題拯救計畫系列 第 21

Flutter中的連結器--MethodChannel

  • 分享至 

  • xImage
  •  

平台特定代碼是指在使用像 Flutter 這樣的跨平台框架時,如果要使用 Android 或 iOS 系統自帶的功能,就需要寫一些專門給這些平台用的原生代碼。雖然 Flutter 本身已經能處理很多功能,但有些特定的功能,像是相機、定位服務等等,還是得靠寫 Android 或 iOS 的原始程式碼來實現。

相機

我們以相機來舉例

  • iOS
    在 iOS 上,通常使用 UIImagePickerController 來打開相機拍照。這是一個 iOS 原始的套件,可以在 Objective-C 或 Swift 來使用設備的相機。

  • Android
    在 Android 上,使用 Intent 來調用相機應用並拍照。

  • Flutter
    在 Flutter 中,可以使用我們之前介紹過的插件(例如 image_picker)來處理相機功能。但是,如果需要更多特殊功能,就需要自己撰寫平台特定代碼。

如何實現

  • 編寫平台特定代碼
    首先,在 Android 的 MainActivity.kt 或 iOS 的 AppDelegate.swift 中編寫相應的原始程式碼。

  • Android (MainActivity.kt)
package com.example.myapp

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

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.myapp/native"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getNativeData") {
                val data = getNativeData()
                result.success(data)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun getNativeData(): String {
        return "Native Android Data"
    }
}
  • iOS (AppDelegate.swift)
import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let nativeChannel = FlutterMethodChannel(name: "com.example.myapp/native",
                                                  binaryMessenger: controller.binaryMessenger)
        nativeChannel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
            if call.method == "getNativeData" {
                result(self.getNativeData())
            } else {
                result(FlutterMethodNotImplemented)
            }
        }

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

    private func getNativeData() -> String {
        return "Native iOS Data"
    }
}
  • Flutter 與平台程式碼連結
    使用 Flutter 的 MethodChannel 來連結並使用這些平台特定的功能。
import 'package:flutter/services.dart';

class CameraAccess {
  static const platform = MethodChannel('com.example/camera');

  Future<void> openCamera() async {
    try {
      final result = await platform.invokeMethod('openCamera');
      print('Camera opened: $result');
    } on PlatformException catch (e) {
      print("Failed to open camera: '${e.message}'.");
    }
  }
}

我們明天見~


上一篇
Flutter中的無障礙設計--Semantics
下一篇
Flutter中的跨平台應用--Flutter Web
系列文
畢業專題拯救計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言