最近准备使用 Flutter 做点小东西,可能会涉及到与原生的交互,参考 使用平台通道编写平台特定的代码 这篇文章实践了一下,记录一下过程和其中遇到的问题。
实践环境说明
- macOS Big Sur
- Vistual Studio Code
- Flutter 1.22.6
- Dart 2.10.5
- Xcode 12.4
创建工程
环境的搭建我略过了,如果有需要可以后续在写一篇实践篇。
- 按照文档,在想要创建工程的文件夹打开命令行,直接使用
flutter create -i swift -a kotlin batterylevel(因为想使用 swift 和 kotlin,如果使用 java 和 Objective-C 可以直接使用flutter create batterylevel命令 )创建一个显示设备电量的工程,这一步没有什么问题。 - 创建完成后在命令行先使用
open -a Simulator打开一个模拟的手机。 - 在命令后内输入 flutter run ,可以使工程在模拟的手机内运行,可以看到一个简易的页面。
添加 Flutter 代码调用函数
- 首先声明一个
MethodChannel,MethodChannel的参数名称为通道名称,在单个应用中应该唯一。
static const platform = const MethodChannel("samples.flutter.io/battery");
- 声明显示电量的字符串
String _batteryLevel = 'Unknown battery level.';
- 声明一个获取电量函数调用原生代码
Future<Null> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result %.';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'. ";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
- 定义控件,一个
RaisedButton用于点击获取电量交互,一个Text用于显示电量。两个控件放到Widget的数组内。
RaisedButton(
child: new Text('Get Battery Level'),
onPressed: _getBatteryLevel,
),
Text(_batteryLevel)
ios 获取电池电量
- 使用 Xcode 打开项目内的 ios 文件夹。
- 打开 AppDelegate.swift 文件,修改 application 函数为
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self);
let controller: FlutterBinaryMessenger = window?.rootViewController as! FlutterBinaryMessenger;
let batteryChannel = FlutterMethodChannel.init(name: "samples.flutter.io/battery", binaryMessenger: controller);
batteryChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: FlutterResult) -> Void in
if ("getBatteryLevel" == call.method) {
receiveBatteryLevel(result: result)
} else {
result(FlutterMethodNotImplemented)
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
不知道是不是因为 Flutter 更新的原因, 这里我参照文档的时候发现文档有个地方有问题。FlutterMethodChannel.init 的 binaryMessenger 参数类型是 FlutterBinaryMessenger, 但是参考文档里面写的是 FlutterViewController, 所以我声明的 controller 是 FlutterBinaryMessenger.
然后在该文件的最后添加获取电池电量函数,参考文档里面 UIDeviceBatteryState 这个提示找不到,后来我查看了 UIDevice 的文档,发现应该是 UIDevice.BatteryState。
private func receiveBatteryLevel(result: FlutterResult) {
let device = UIDevice.current;
device.isBatteryMonitoringEnabled = true;
if (device.batteryState == UIDevice.BatteryState.unknown) {
result(FlutterError.init(code: "UNAVAILABLE", message: "Battery info unavailable", details: nil))
} else {
result(Int(device.batteryLevel * 100))
}
}
运行程序
在工程目录打开命令行,输入 flutter run,运行项目,稍等一会 app 会安装到模拟的手机中,点击 Get Battery Level 按钮,发现电量显示 Battery info unavailable。我发现是因为模拟器的 UIDevice.batteryState 就是为UIDevice.BatteryState.unknown,所以为了测试获取电量正确还得连接真机。
如果需要连接真机得设置 Signing & Capabilities , 点击 Runner ,在页面中选择 Signing & Capabilities,在 Team 的选择框中选择 Add an Account,输入自己的 Apply Id 用户名和密码就可以了,成功后确保没有报错,我遇到输入的 Bundle Identifier 已经存在,重新换一个就好了。如果有报错会在这个页面的 Status 里面显示,仔细阅读可以解决。我之前网上搜索说需要添加 iOS Development,但是我的 Xcode 是不需要的,只有一个 Apple Development。连接上真机后,继续 flutter run。然后点击 Get Battery Level 按钮,发现可以显示出实际的电量。到此 Flutter 调用 iOS 就完成了。
注意:需要在 iPhone 的设置中信任该 app
如果你有多个设备,可以先使用 flutter devices 查看设备的 id。
然后 flutter run -d 设备ID,指定运行的设备。
其他问题
- 遇到 Xcode 工程中的
Debug.xcconfig和Release.xcconfig引用了Generated.xcconfig,但是项目中没有Generated.xcconfig,可以按照下面步骤解决- flutter clean (in terminal)
- flutter build (in terminal)
- In Xcode, then clean project
- In Xcode, then build project
- 提示 Info.plist does not exist. The Flutter "Thin Binary" build phase must run after "Copy Bundle Resources". 我 clean 一下之后在重新 build 解决了。
参考资料
- 使用平台通道编写平台特定的代码
- UIDevice
- Could not find included file 'Generated.xcconfig' in search paths (in target 'Runner')
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!