赞
踩
类似在React Native项目中一样,当Flutter提供功能或者已存在的插件不能满足项目需要的时候就需要我们自己编写原生代码的插件以供Dart代码使用。
根据官方图片的介绍:
Flutter中通过FlutterMethodChannel与原生代码之间进行通信,而在Android中则使用MethodChannel。
编写测试项目代码,根据官方文档的说明采用获取手机电量来说明。
Dart端代码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Channel Demo") ), body: Center(child: DemoWidget()) ) ); } } class DemoWidget extends StatefulWidget { @override _DemoWidgetState createState() => _DemoWidgetState(); } class _DemoWidgetState extends State<DemoWidget> { // 定义MethodChannel,原生代码会使用这个字符串来做匹配 static const platform = const MethodChannel('com.channel_demo.text/battery'); String _batteryLevel = 'Unknown battery level.'; Future<Null> _getBatteryLevel() async { String batteryLevel; try { // 调用原生端提供的方法 final int result = await platform.invokeMethod('getBatteryLevel', "dart端传递的参数"); print("result = $result"); batteryLevel = "$result"; } on PlatformException catch (e) { batteryLevel = "Failed to get battery level: '${e.message}'."; } setState(() { _batteryLevel = batteryLevel; }); } @override Widget build(BuildContext context) { return Column( children: <Widget>[ Text("当前电量的值 = $_batteryLevel"), RaisedButton( child: Text("获取手机电量"), onPressed: (() { _getBatteryLevel(); }), ) ], ); } }
在AppDelegate中的didFinishLaunchingWithOptions方法中监听方法调用,编写对应逻辑。
@UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller: FlutterViewController = window.rootViewController as! FlutterViewController let batteryChannel = FlutterMethodChannel(name: "com.channel_demo.text/battery", binaryMessenger: controller as! FlutterBinaryMessenger) batteryChannel.setMethodCallHandler { (call, result) in if ("getBatteryLevel" == call.method) { print("获取dart端传递的参数 arguments = \(call.arguments)") self.receiveBatteryLevel(result: result) } else { result(FlutterMethodNotImplemented) } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func receiveBatteryLevel(result: FlutterResult) { let device = UIDevice.current; device.isBatteryMonitoringEnabled = true; if (device.batteryState == UIDevice.BatteryState.unknown) { result(FlutterError.init(code: "UNAVAILABLE", message: "电池信息不可用", details: nil)); } else { result(Int(device.batteryLevel * 100)); } } }
Android端需要在MainActivity重写configureFlutterEngine方法。
class MainActivity: FlutterActivity() { private val Battery_channel = "com.channel_demo.text/battery" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, Battery_channel).setMethodCallHandler { methodCall, result -> if (methodCall.method == "getBatteryLevel") { val batteryLevel = getBatteryLevel() if (batteryLevel != -1) { result.success(batteryLevel) } else { result.error("UNAVAILABLE", "Battery level not available.", null) } } else { result.notImplemented() } } } private fun getBatteryLevel(): Int { val batteryLevel: Int batteryLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) } else { val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1) } return batteryLevel } }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。