HarmonyOS 鸿蒙系统专项指南

本文档介绍如何在 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 优先逻辑),鸿蒙开发者显式精确锁定即可。

鸿蒙端已支持的核心能力:

  • 地图渲染(普通 / 卫星 / 暗色 / 3D 沉浸 4 种地图类型)、路况、3D 建筑、标注、指南针、比例尺、Logo 位置、手势开关、缩放范围与显示范围限制
  • 相机控制(中心点、缩放、旋转、倾斜,8 种 CameraUpdate 工厂方法)
  • 点标记 Marker(自定义图标、旋转、透明度、缩放、InfoWindow、碰撞控制)
  • 折线 Polyline(实线、虚线、纹理、渐变、分段着色、箭头)
  • 多边形 Polygon(含镂空洞、虚线描边)、圆形 Circle、弧线 Arc
  • 定位图层(定位蓝点、精度圆、自定义图标,MyLocationStyleOptions 样式)
  • 地图事件(点击、长按、POI 点击、相机变化)
  • 地图查询(坐标与屏幕坐标互转、批量转换、可视区域)与地图截图
  • 个性化地图样式、多地图实例

与 Android/iOS 不一致的能力见第八节。


二、前置条件

2.1 开发环境

项目 要求
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 分支。

2.2 鸿蒙平台要求

项目 要求
compatibleSdkVersion 5.0.0(12)(OpenHarmony 5.0.0.71+ / API 12+)
runtimeOS HarmonyOS
签名 签名三件套(.cer / .p7b / .p12),必须配置
Java 17.0(hvigor 构建工具链要求)

三、安装

3.1 添加依赖

在项目的 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 依赖自动引入,无需手动安装。

3.2 获取鸿蒙 API Key

  1. 前往腾讯位置服务控制台注册账号并创建应用
  2. 创建 HarmonyOS 平台 的 Key(绑定应用的 Bundle Name 与签名指纹)

注意:HarmonyOS 平台的 Key 与 Android/iOS 不同,必须单独申请。

ohosSecretKey 是可选的签名增强:不填走普通鉴权(校验 Key + 应用签名指纹),推荐先用这种方式验证;若填写则走签名鉴权,必须是控制台生成的真实 SecretKey,填占位符或假值会导致鉴权失败。


四、平台配置

4.1 声明权限

在 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 并在运行时动态申请。

4.2 配置签名

鸿蒙工程必须配置签名三件套(.cer / .p7b / .p12)。推荐在 DevEco Studio 中配置:

File → Project Structure → Signing Configs → 勾选 Automatically generate signature(需登录华为开发者账号),会自动写入 ohos/build-profile.json5 的 signingConfigs。

注意:签名材料是鸿蒙应用安装的必要条件,未配置签名无法运行到真机。签名证书与 bundleName 绑定,修改 bundleName 后需重新生成。

4.3 编译配置

在 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: () {
            // 地图控制器就绪
          },
        ),
      ),
    );
  }
}

注意:鸿蒙端 TencentMap Widget 的 apiKey 参数不需要重复传入(已通过 setApiKey 全局设置),与 Android/iOS 的 apiKey 传入方式不同。

示例工程:完整可运行的示例见 Demo 工程 flutter_tencent_map_demo_ohos(含 Android / iOS / HarmonyOS 三端,三端统一使用 flutter-ohos 构建,运行说明见其 README.md,下载见下载),覆盖地图配置、相机、覆盖物、定位图层、坐标查询与截图等场景。


七、构建与调试

7.1 构建 HAP 包

鸿蒙工程使用 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 的命令封装(按你的实际配置替换)

7.2 产物位置

  • Debug HAP:build/ohos/hap/entry-default-signed.hap
  • Release HAP:build/ohos/hap/entry-default-signed.hap(--release)

7.3 安装到设备

通过 DevEco Studio 的"运行"按钮直接安装到鸿蒙设备/模拟器,或使用 hdc 工具:

hdc install build/ohos/hap/entry-default-signed.hap

7.4 日志调试

// 开启插件层日志(观察覆盖物增删改链路),hilog 中搜索 FlutterTencentMap
await TencentMapInitializer.enableFlutterPluginLog();
hdc shell hilog | grep FlutterTencentMap

八、与 Android/iOS 的功能差异

图例:❌ 未实现(Flutter 接口存在,鸿蒙端设置后被忽略,不会报错)/⬇️ 降级/⚠️ 行为不同。

8.1 Marker(点标记)

能力 鸿蒙状态 说明
draggable(拖拽) ❌ 未实现 设置后无效果,onDragStart / onDrag / onDragEnd 回调也不会触发
fixedToScreen / fixedScreenPoint(固定屏幕锚点) ❌ 未实现 鸿蒙无固定屏幕位置 API
infoWindow ⚠️ 行为不同 InfoWindow 由插件自绘,样式与 Android/iOS 原生样式不完全相同;标题/副标题单行显示,超长尾部省略;title 为空时不显示(只有 snippet 不会弹出)

8.2 Polyline(折线)

能力 鸿蒙状态 说明
lineCap(线帽样式) ❌ 未实现 鸿蒙无线帽圆角/方角切换 API
textureLineType: footprint(足迹线) ⬇️ 降级 降级为普通实线(按 color / segmentColors 绘制),纹理被忽略

8.3 Polygon(多边形)

能力 鸿蒙状态 说明
strokeTexture / strokeTextureSpacing(描边纹理) ❌ 未实现 鸿蒙 SDK 不支持多边形描边纹理,静默忽略

8.4 Arc(弧线)

能力 鸿蒙状态 说明
showArrow(箭头) ❌ 未实现 鸿蒙 SDK 不支持弧线箭头,静默忽略

8.5 定位图层

能力 鸿蒙状态 说明
myLocationType: mapRotateNoCenter ⚠️ 行为不同 地图旋转无动画,立即生效
精度圈(circleFillColor / circleStrokeColor / circleStrokeWidth) ⚠️ 插件自绘 鸿蒙 SDK 无内置精度圈,由插件绘制;某个样式字段由有值改回 null 时,保持上一次的样式,不会恢复默认值
updateMyLocation ⚠️ 部分字段 仅使用 latLng / bearing / accuracy,speed / altitude 被忽略

8.6 地图与相机

能力 鸿蒙状态 说明
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 被忽略

8.7 多地图实例

能力 鸿蒙状态 说明
多地图并存、事件隔离 ✅ 支持 每个 TencentMap 实例独立
不同地图使用不同 Key ❌ 暂不支持 鉴权为全局单例,同一应用内所有地图共用同一个 ohosKey

九、常见问题排查

9.1 地图白屏 / 无法显示

排查步骤:

  1. 检查鉴权:鸿蒙端必须调用 TencentMapInitializer.setApiKey(含 ohosKey),且在任何地图 Widget 创建前。漏掉此步骤地图会白屏。若填写了 ohosSecretKey,确认是真实值而非占位符。
  2. 检查 Key 绑定:确认 ohosKey 绑定的 Bundle Name 与签名指纹和当前安装的应用一致。
  3. 检查隐私合规:确认已调用 TencentMapInitializer.setAgreePrivacy(true)。
  4. 检查签名:鸿蒙工程必须配置签名三件套,未配置无法运行到真机。
  5. 检查权限与网络:确认 module.json5 已声明 ohos.permission.INTERNET,设备网络可用。
  6. 检查设备:确认设备/模拟器为 OpenHarmony 5.0.0.71+ / API 12+。

9.2 构建失败:Unsupported class file major version 61

原因:hvigor 要求 Java 17,如果 JAVA_HOME 指向其他版本(如 Java 11)会报此错。

解决:

export JAVA_HOME="/path/to/java17"
flutter-ohos build hap --debug

9.3 构建失败: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

9.4 flutter-ohos: command not found

原因:flutter-ohos 是社区推荐别名,不是 fork 自带命令。

解决:

  • 配置别名(见前置条件),或
  • 直接调用 fork 的 flutter:$HOME/path/to/flutter_flutter/bin/flutter build hap --debug

9.5 升级主线版本后鸿蒙能力丢失

原因:鸿蒙用户写了 ^1.0.1-ohos.1(caret 约束),主线 stable 版本会静默覆盖鸿蒙版。

解决:鸿蒙用户必须精确锁定 1.0.1-ohos.1(不能写 ^ 约束)。

9.6 构建失败:Bytecode HARs not supported

原因:build-profile.json5 缺少 useNormalizedOHMUrl 配置,腾讯地图鸿蒙 SDK 是字节码 HAR。

解决:按4.3 编译配置在 products[].buildOption.strictMode 下添加 "useNormalizedOHMUrl": true。

9.7 构建失败:找不到 AxisEvent / getDistance 等类型

原因:DevEco Studio 内置的 OpenHarmony SDK 版本过低(API < 18),缺少 flutter-ohos 引擎代码引用的类型声明。

解决:在 DevEco Studio 中升级 OpenHarmony SDK 到 API 18 及以上(compatibleSdkVersion 无需改动,保持 5.0.0(12))。


本页内容