本文档介绍如何在 HarmonyOS(鸿蒙)系统中使用 flutter_tencent_map 插件,包括鸿蒙专项版的安装、平台配置、初始化鉴权、快速开始,以及与 Android/iOS 的功能差异说明。
⚠️ 适用版本:鸿蒙专项版
1.0.1-ohos.1(pre-release)。本文仅适用于 flutter-ohos fork SDK 开发的鸿蒙工程,主线 Google Flutter SDK 开发的 Android/iOS 工程请阅读集成 Flutter 插件。
flutter_tencent_map 的鸿蒙适配以**专项版本(pre-release)**形式发布,与主线版本号分离:
| 版本类型 | 版本号 | 适用场景 | 底层 SDK |
|---|---|---|---|
| 主线版 | ^1.0.0 |
Android / iOS(主线 Flutter) | 腾讯地图 Android 5.9.0+ / iOS 5.7.7+ |
| 鸿蒙专项版 | 1.0.1-ohos.1 |
HarmonyOS(flutter-ohos fork) | @tencentmap/map 2.6.0 + @tencentmap/base 2.3.3 |
为什么用 pre-release 版本号:
1.0.1-ohos.1的lib/内含TargetPlatform.ohos/OhosView等 flutter-ohos fork 独有符号,主线 Flutter SDK 编译必然失败。pre-release 版本号让主线用户^1.0.0约束自动回避(pub solver 的 stable 优先逻辑),鸿蒙开发者显式精确锁定即可。
鸿蒙端已支持的核心能力:
CameraUpdate 工厂方法)MyLocationStyleOptions 样式)与 Android/iOS 不一致的能力见第八节。
| 项目 | 要求 |
|---|---|
| Flutter SDK | flutter-ohos fork 3.22.1-ohos-1.0.9(⚠️ 必须,非主线 Flutter) |
| Dart | 3.4.0(随 flutter-ohos 自带) |
| DevEco Studio | 最新稳定版;其内置的 OpenHarmony SDK 需 ≥ API 18(compatibleSdkVersion 仍保持 5.0.0(12),见 2.2) |
| 鸿蒙设备/模拟器 | OpenHarmony 5.0.0.71+ / API 12+ |
关于
flutter-ohos:它是 OpenHarmony 社区 fork(flutter_flutter)的命令封装,不是 fork 自带的命令名。fork 安装后其bin/目录里的命令是flutter(与主线同名),推荐配置别名避免冲突:# 推荐:配置别名(不影响主线 flutter) alias flutter-ohos="$HOME/path/to/flutter_flutter/bin/flutter"本文档中所有
flutter-ohos命令,请按你的实际配置替换(或直接调用 fork 的flutter)。 安装 flutter_flutter fork:git clone https://gitcode.com/openharmony-tpc/flutter_flutter.git,切换到3.22.1-ohos-1.0.9分支。
| 项目 | 要求 |
|---|---|
compatibleSdkVersion |
5.0.0(12)(OpenHarmony 5.0.0.71+ / API 12+) |
runtimeOS |
HarmonyOS |
| 签名 | 签名三件套(.cer / .p7b / .p12),必须配置 |
| Java | 17.0(hvigor 构建工具链要求) |
在项目的 pubspec.yaml 中精确锁定鸿蒙专项版:
dependencies:
flutter_tencent_map: 1.0.1-ohos.1 # ⚠️ 必须精确锁定,不能写 ^1.0.1-ohos.1
⚠️ 为什么必须精确锁定:
^1.0.1-ohos.1允许解析到>=1.0.1-ohos.1 <2.0.0范围内任意版本,未来主线 stable(如1.0.2)会静默覆盖鸿蒙版。鸿蒙开发者必须写精确版本号。
然后执行:
flutter-ohos pub get # 鸿蒙需使用 flutter_flutter fork SDK
腾讯地图鸿蒙 SDK(
@tencentmap/map、@tencentmap/base)由插件通过 ohpm 依赖自动引入,无需手动安装。
注意:HarmonyOS 平台的 Key 与 Android/iOS 不同,必须单独申请。
ohosSecretKey是可选的签名增强:不填走普通鉴权(校验 Key + 应用签名指纹),推荐先用这种方式验证;若填写则走签名鉴权,必须是控制台生成的真实 SecretKey,填占位符或假值会导致鉴权失败。
在 ohos/entry/src/main/module.json5 的 requestPermissions 中至少声明网络权限:
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" }
]
如果你的应用需要自行获取设备定位并通过 updateMyLocation 推送到定位图层,还需声明位置权限(插件本身不会申请位置权限,授权与定位由业务层负责):
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" },
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:location_reason",
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:location_reason",
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
}
// 如需后台定位(导航):
// { "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" },
// { "name": "ohos.permission.LOCATION_IN_BACKGROUND" }
]
位置权限属于用户授权权限,需按 HarmonyOS 要求补充
reason/usedScene并在运行时动态申请。
鸿蒙工程必须配置签名三件套(.cer / .p7b / .p12)。推荐在 DevEco Studio 中配置:
File → Project Structure → Signing Configs → 勾选 Automatically generate signature(需登录华为开发者账号),会自动写入 ohos/build-profile.json5 的 signingConfigs。
注意:签名材料是鸿蒙应用安装的必要条件,未配置签名无法运行到真机。签名证书与
bundleName绑定,修改bundleName后需重新生成。
在 ohos/build-profile.json5 的 products 中确认以下配置:
{
"app": {
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.0(12)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"useNormalizedOHMUrl": true
}
}
}
]
}
}
⚠️
useNormalizedOHMUrl: true必须配置:腾讯地图鸿蒙 SDK 是字节码 HAR,hvigor 要求开启该选项才能链接,缺失会报Bytecode HARs not supported类错误。该选项只能放在buildOption.strictMode下。
鸿蒙端的初始化与 Android/iOS 不同,必须调用 TencentMapInitializer.setApiKey 完成鉴权(AuthService 全局单例)。
import 'package:flutter/material.dart';
import 'package:flutter_tencent_map/flutter_tencent_map.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 1. 隐私合规(必须在使用地图前调用)
await TencentMapInitializer.setAgreePrivacy(true);
// 2. API Key 设置
// ⚠️ HarmonyOS 必需:AuthService 全局单例鉴权,必须在任何地图 Widget 创建前调用。
// Android/iOS 为 no-op(Key 在 AndroidManifest / Info.plist / TencentMap(apiKey:) 传入)。
// ohosSecretKey 为可选项,不填走普通鉴权;若填写必须是真实 SecretKey,不要填占位符。
await TencentMapInitializer.setApiKey(const TencentMapApiKey(
androidKey: 'YOUR_ANDROID_KEY',
iosKey: 'YOUR_IOS_KEY',
ohosKey: 'YOUR_OHOS_KEY',
));
// 3. 初始化 SDK
await TencentMapInitializer.start();
runApp(const MyApp());
}
⚠️ 鸿蒙特殊要求:
setApiKey是鸿蒙端真正的鉴权入口(AuthService全局单例),必须在任何地图 Widget 创建前调用,否则地图无法显示ohosKey必需;ohosSecretKey可选(见 3.2)- Android/iOS 端此方法为 no-op,因此三端
main.dart代码可完全统一,无需平台分支- 由于鉴权是全局单例,同一应用内所有地图实例共用同一个
ohosKey
以下示例展示鸿蒙端从初始化到显示地图 + Marker 的完整流程:
import 'package:flutter/material.dart';
import 'package:flutter_tencent_map/flutter_tencent_map.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await TencentMapInitializer.setAgreePrivacy(true);
await TencentMapInitializer.setApiKey(const TencentMapApiKey(
ohosKey: 'YOUR_OHOS_KEY',
));
await TencentMapInitializer.start();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('腾讯地图 · 鸿蒙')),
body: TencentMap(
initialCameraPosition: const CameraPosition(
target: LatLng(39.9087, 116.3975), // 天安门
zoom: 12,
),
markers: {
Marker(
id: 'm1',
position: const LatLng(39.9087, 116.3975),
infoWindow: const InfoWindow(
title: '天安门',
snippet: '北京市东城区',
),
),
},
onMapCreated: (controller) {
// 地图创建完成
},
onMapLoaded: () {
// 地图控制器就绪
},
),
),
);
}
}
注意:鸿蒙端
TencentMapWidget 的apiKey参数不需要重复传入(已通过setApiKey全局设置),与 Android/iOS 的apiKey传入方式不同。
示例工程:完整可运行的示例见 Demo 工程
flutter_tencent_map_demo_ohos(含 Android / iOS / HarmonyOS 三端,三端统一使用 flutter-ohos 构建,运行说明见其README.md,下载见下载),覆盖地图配置、相机、覆盖物、定位图层、坐标查询与截图等场景。
鸿蒙工程使用 hvigor 工具链构建(非 Gradle),命令:
export JAVA_HOME="/path/to/java17" # hvigor 要求 Java 17
export DEVECO_SDK_HOME="/path/to/DevEco-Studio/sdk"
flutter-ohos build hap --debug
环境变量说明:
JAVA_HOME:hvigor 要求 Java 17(与 Android 构建的 Java 11 不同)DEVECO_SDK_HOME:DevEco Studio 的 SDK 目录(macOS 通常为/Applications/DevEco-Studio.app/Contents/sdk)flutter-ohos:flutter_flutter fork 的命令封装(按你的实际配置替换)
build/ohos/hap/entry-default-signed.hapbuild/ohos/hap/entry-default-signed.hap(--release)通过 DevEco Studio 的"运行"按钮直接安装到鸿蒙设备/模拟器,或使用 hdc 工具:
hdc install build/ohos/hap/entry-default-signed.hap
// 开启插件层日志(观察覆盖物增删改链路),hilog 中搜索 FlutterTencentMap
await TencentMapInitializer.enableFlutterPluginLog();
hdc shell hilog | grep FlutterTencentMap
图例:❌ 未实现(Flutter 接口存在,鸿蒙端设置后被忽略,不会报错)/⬇️ 降级/⚠️ 行为不同。
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
draggable(拖拽) |
❌ 未实现 | 设置后无效果,onDragStart / onDrag / onDragEnd 回调也不会触发 |
fixedToScreen / fixedScreenPoint(固定屏幕锚点) |
❌ 未实现 | 鸿蒙无固定屏幕位置 API |
infoWindow |
⚠️ 行为不同 | InfoWindow 由插件自绘,样式与 Android/iOS 原生样式不完全相同;标题/副标题单行显示,超长尾部省略;title 为空时不显示(只有 snippet 不会弹出) |
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
lineCap(线帽样式) |
❌ 未实现 | 鸿蒙无线帽圆角/方角切换 API |
textureLineType: footprint(足迹线) |
⬇️ 降级 | 降级为普通实线(按 color / segmentColors 绘制),纹理被忽略 |
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
strokeTexture / strokeTextureSpacing(描边纹理) |
❌ 未实现 | 鸿蒙 SDK 不支持多边形描边纹理,静默忽略 |
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
showArrow(箭头) |
❌ 未实现 | 鸿蒙 SDK 不支持弧线箭头,静默忽略 |
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
myLocationType: mapRotateNoCenter |
⚠️ 行为不同 | 地图旋转无动画,立即生效 |
精度圈(circleFillColor / circleStrokeColor / circleStrokeWidth) |
⚠️ 插件自绘 | 鸿蒙 SDK 无内置精度圈,由插件绘制;某个样式字段由有值改回 null 时,保持上一次的样式,不会恢复默认值 |
updateMyLocation |
⚠️ 部分字段 | 仅使用 latLng / bearing / accuracy,speed / altitude 被忽略 |
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
customStyleOptions |
⚠️ 行为不同 | styleId 必须 ≥ 1;enabled: false 或传 null 无法恢复默认样式(需重建地图) |
moveCamera / animateCamera 的 duration |
❌ 未实现 | 动画时长由 SDK 决定,参数被忽略 |
CameraUpdate.newLatLngBounds 的 padding |
⚠️ 行为不同 | 四边内边距取最大值统一应用 |
相机 bearing / tilt 变化 |
⚠️ 无动画 | 立即生效 |
onMapLoaded |
⚠️ 触发时机不同 | 鸿蒙端在地图控制器就绪时触发,早于瓦片渲染完成 |
TencentMapInitializer.clearCache() |
❌ 未实现 | 恒返回 false |
TencentMapInitializer.enableSdkLog |
⚠️ 部分字段 | 鸿蒙端读取 androidConfig 的 enable / level / toConsole / toFile;iosConfig、tags、fileSizeLimitMB、fileCacheDays 被忽略 |
| 能力 | 鸿蒙状态 | 说明 |
|---|---|---|
| 多地图并存、事件隔离 | ✅ 支持 | 每个 TencentMap 实例独立 |
| 不同地图使用不同 Key | ❌ 暂不支持 | 鉴权为全局单例,同一应用内所有地图共用同一个 ohosKey |
排查步骤:
TencentMapInitializer.setApiKey(含 ohosKey),且在任何地图 Widget 创建前。漏掉此步骤地图会白屏。若填写了 ohosSecretKey,确认是真实值而非占位符。ohosKey 绑定的 Bundle Name 与签名指纹和当前安装的应用一致。TencentMapInitializer.setAgreePrivacy(true)。module.json5 已声明 ohos.permission.INTERNET,设备网络可用。Unsupported class file major version 61原因:hvigor 要求 Java 17,如果 JAVA_HOME 指向其他版本(如 Java 11)会报此错。
解决:
export JAVA_HOME="/path/to/java17"
flutter-ohos build hap --debug
DEVECO_SDK_HOME not set / 00303217 Configuration Error原因:hvigor 找不到 DevEco Studio SDK。
解决:
export DEVECO_SDK_HOME="/Applications/DevEco-Studio.app/Contents/sdk"
flutter-ohos build hap --debug
flutter-ohos: command not found原因:flutter-ohos 是社区推荐别名,不是 fork 自带命令。
解决:
flutter:$HOME/path/to/flutter_flutter/bin/flutter build hap --debug原因:鸿蒙用户写了 ^1.0.1-ohos.1(caret 约束),主线 stable 版本会静默覆盖鸿蒙版。
解决:鸿蒙用户必须精确锁定 1.0.1-ohos.1(不能写 ^ 约束)。
Bytecode HARs not supported原因:build-profile.json5 缺少 useNormalizedOHMUrl 配置,腾讯地图鸿蒙 SDK 是字节码 HAR。
解决:按4.3 编译配置在 products[].buildOption.strictMode 下添加 "useNormalizedOHMUrl": true。
AxisEvent / getDistance 等类型原因:DevEco Studio 内置的 OpenHarmony SDK 版本过低(API < 18),缺少 flutter-ohos 引擎代码引用的类型声明。
解决:在 DevEco Studio 中升级 OpenHarmony SDK 到 API 18 及以上(compatibleSdkVersion 无需改动,保持 5.0.0(12))。
有帮助
没帮助