Day15 开发套件 - 实作MethodChannel

Flutter 端:

lib/batterylevel.dart:新增取得电池电量资讯方法,透过建立的MethodChannel传入方法名来呼叫Native 端对应的getBatteryLevel方法

  static Future<String?> get batteryLevel async {
    final String? batteryLevel = await _channel.invokeMethod('getBatteryLevel');
    return batteryLevel;
  }

Native 端(Android):

android/.../BatterylevelPlugin.kt

这边会取得电量会需要android 的applicationContext,所以我们新增一个applicationContext属性,在onAttachedToEngine时透过flutterPluginBinding取得,并在onDetachedFromEngine释放

最後新增一个方法getBatteryLevel来处理取得电量资讯的动作

最後在onMethodCall的地方实现从Flutter 端要调用的getBatteryLevel方法

class BatterylevelPlugin : FlutterPlugin, MethodCallHandler {
    private lateinit var channel: MethodChannel
    private var applicationContext: Context? = null

    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        applicationContext = flutterPluginBinding.applicationContext
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "batterylevel")
        channel.setMethodCallHandler(this)
    }

    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
        if (call.method == "getPlatformVersion") {
            result.success("Android ${android.os.Build.VERSION.RELEASE}")
        } else if (call.method == "getBatteryLevel") {
            val batterLevel = getBatteryLevel()
            if (batterLevel != -1) {
                result.success("Android batterLevel = $batterLevel%")
            } else {
                result.error("UNAVAILABLE", "Battery level not available.", null);
            }
        } else {
            result.notImplemented()
        }
    }

    override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        applicationContext = null;
        channel.setMethodCallHandler(null)
    }

    private fun getBatteryLevel(): Int {
        var batteryLevel = -1
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val batteryManager =
                applicationContext?.let { getSystemService(it, BatteryManager::class.java) }
            batteryLevel = batteryManager!!.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
        } else {
            ContextWrapper(applicationContext).registerReceiver(
                null,
                IntentFilter(Intent.ACTION_BATTERY_CHANGED)
            )?.apply {
                batteryLevel = getIntExtra(
                    BatteryManager.EXTRA_LEVEL,
                    -1
                ) * 100 / getIntExtra(BatteryManager.EXTRA_SCALE, -1)
            }
        }

        return batteryLevel
    }
}

Native 端(iOS):

同样新增一个方法getBatteryLevel来处理取得电量资讯的动作,最後在handle实现从Flutter 端要调用的getBatteryLevel方法

public class SwiftBatterylevelPlugin: NSObject, FlutterPlugin {
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "batterylevel", binaryMessenger: registrar.messenger())
        let instance = SwiftBatterylevelPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }
    
    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        switch call.method {
        case "getPlatformVersion":
            result("iOS " + UIDevice.current.systemVersion)
        case "getBatteryLevel":
            let batterLevel = getBatteryLevel()
            if(batterLevel == -1) {
                result(FlutterError(code: "UNAVAILABLE", message: "Battery info unavailable", details: nil));
            } else {
                result("iOS batterLevel = \(batterLevel * 100)%")
            }
        default:
            result(FlutterMethodNotImplemented)
        }
    }
    
    private func getBatteryLevel() -> Float {
        let device = UIDevice.current
        device.isBatteryMonitoringEnabled = true
        if device.batteryState == .unknown {
            return -1;
        } else {
            return UIDevice.current.batteryLevel
        }
    }
}

这样就完成获得设备电池电量资讯的插件功能了,并了解对MethodChannel的实作步骤流程,接下来让我们看看其他的Channel要如何实作吧


<<:  (完结).NET Core第30天_Controller Action的各种不同回传

>>:  Day15 Combine 02 - Publisher

[Python 爬虫这样学,一定是大拇指拉!] DAY22 - 实战演练:HTML Response - 抓取股票代码清单 (1)

承接上篇,抓日成交资讯时,我们得知道股票代码,那如果我想要有一个可以定时更新的股票代码清单,要去哪里...

Day08 - this&Object Prototypes Ch3 Objects - Contents - [[Get]]

Object 本身自带 [[Get]] 机制能帮我们找到符合 property name (或说 k...

[Day24]创建Table及捞取资料

创建migration迁移档案 首先先使用artisan指令: make:migration 创建一...

Day 15:更多开源专案

JUCE 在「声音处理」领域的知名度高,除了 GUI 元件可高度客制化,最重要的是 JUCE 提供的...

Day29 Lab 2 - Object storage数据压缩

资料的压缩最好是能做在前端,因为网路最慢的地方就是前後端的沟通了,现在的压缩演算法有很多,举凡gzi...