

在上一篇文章中,我们成功让 “Hello World!” 出现在 HarmonyOS 模拟器上。 但真正的应用,从来不只是显示文字——它需要访问设备能力:拍照、定位、读取传感器…… 这就是 平台通道(Platform Channel) 的用武之地。
本文将深入讲解:如何在 Flutter for HarmonyOS 项目中,安全、高效地调用鸿蒙原生 API,打通 Dart 与 ArkTS 的“任督二脉”。
尽管 Flutter 提供了丰富的 UI 组件和跨平台逻辑,但以下场景仍需依赖操作系统原生能力:
功能 | 是否有纯 Dart 实现? | 是否需原生调用? |
|---|---|---|
相机拍照 | 部分(通过 camera 插件) | ✅ 需要(底层驱动) |
获取地理位置 | 有插件(如 geolocator) | ✅ 需要(权限+系统服务) |
蓝牙通信 | 社区插件有限 | ✅ 强烈建议 |
访问联系人 | ❌ 无官方支持 | ✅ 必须 |
系统通知 | 部分支持 | ✅ 推荐 |
💡 在 HarmonyOS 上,这些能力由 ArkTS + Native API 提供,而 Flutter 本身并不直接支持。因此,我们必须建立 Dart ↔ ArkTS 的双向通信桥梁。
Flutter 官方推荐使用 MethodChannel 实现平台间通信。其原理如下:
Dart (Flutter) ←—— MethodChannel ——→ ArkTS (HarmonyOS)
↑ ↑
调用方法 处理请求
接收结果 返回数据MethodChannel.invokeMethod() 发起调用result.success() 或 result.error() 返回Future 接收结果我们将以一个简单但典型的例子演示全过程:从 Flutter 中获取鸿蒙设备的型号(如 HUAWEI P60)。
📌 注意:本例基于 DevEco Studio + Flutter for HarmonyOS 项目模板。
在 lib/main.dart 中添加:
import 'package:flutter/services.dart';
// 定义 channel 名称(必须与 ArkTS 一致)
const platform = MethodChannel('com.example.flutter_harmonyos/device_info');
class HelloWorldScreen extends StatefulWidget {
const HelloWorldScreen({super.key});
@override
State<HelloWorldScreen> createState() => _HelloWorldScreenState();
}
class _HelloWorldScreenState extends State<HelloWorldScreen> {
String _deviceModel = 'Unknown';
Future<void> _getDeviceModel() async {
try {
final String model = await platform.invokeMethod('getDeviceModel');
setState(() {
_deviceModel = model;
});
} on PlatformException catch (e) {
_deviceModel = 'Failed: ${e.message}';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Native Call Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Device Model: $_deviceModel'),
ElevatedButton(
onPressed: _getDeviceModel,
child: const Text('Get Device Model'),
),
],
),
),
);
}
}在 HarmonyOS 主模块中(通常是 entry/src/main/ets/EntryAbility.ts 或新建 DevicePlugin.ets),添加:
// DevicePlugin.ets
import { BusinessError } from '@ohos/base';
import deviceInfo from '@ohos.deviceInfo';
export class DevicePlugin {
static register(context: any): void {
const channel = new context.MethodChannel('com.example.flutter_harmonyos/device_info');
channel.setMethodCallHandler((call, result) => {
if (call.method === 'getDeviceModel') {
try {
// 调用鸿蒙原生 API
const model = deviceInfo.model;
result.success(model);
} catch (error) {
const err = error as BusinessError;
result.error(err.code.toString(), err.message, null);
}
} else {
result.notImplemented();
}
});
}
}然后在 EntryAbility.onCreate() 中注册插件:
// EntryAbility.ts
import { DevicePlugin } from './DevicePlugin';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 注册 Flutter 插件
DevicePlugin.register(this.context);
}
}某些功能(如位置、相机)需要在 module.json5 中声明权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.GET_DEVICE_INFO"
}
]
}
}✅
deviceInfo.model只需要GET_DEVICE_INFO权限,该权限为 normal 权限,无需动态申请。
点击按钮后,界面将显示:
Device Model: HUAWEI P60或模拟器上的型号(如 Emulator)。
MethodChannel 支持以下数据类型自动转换:
Dart 类型 | ArkTS 类型 |
|---|---|
String | string |
int / double | number |
bool | boolean |
List | Array |
Map | Object |
例如,返回设备信息对象:
// Dart
final Map<dynamic, dynamic> info = await platform.invokeMethod('getDeviceInfo');
print(info['model']); // HUAWEI P60
print(info['brand']); // HUAWEI// ArkTS
if (call.method === 'getDeviceInfo') {
result.success({
model: deviceInfo.model,
brand: deviceInfo.brand,
osType: deviceInfo.osType
});
}MethodChannel 未注册,调用失败onCreate 中注册DevicePlugin.register() 被调用module.json5 声明权限,或用户拒绝requestPermissionsyour.package/plugin_nameasync/await:防止阻塞主线程HiLog)一旦掌握基础通信,你就可以实现:
功能 | 所需鸿蒙 API |
|---|---|
调用相机 | @ohos.multimedia.camera |
获取位置 | @ohos.location.geolocation |
蓝牙扫描 | @ohos.bluetoothManager |
发送通知 | @ohos.notification |
读取联系人 | @ohos.contacts |
🔗 官方 API 文档:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V5
通过 MethodChannel,我们不仅让 Flutter 在鸿蒙上“能跑”,更让它“能用”。 这不再是简单的 UI 渲染,而是深度融入操作系统的能力调用。
未来,随着 @ohos/flutter_ohos 生态的成熟,或许会有更多官方插件出现。但在那之前,掌握原生调用,是你掌控全平台的关键技能。