HarmonyOS开发——鸿蒙 uni.openLocation 地图空白排障记:那个 key 到底该怎么配

脱敏说明:文中尖括号/x 占位符均为脱敏项 —— <鸿蒙应用的 DCloud AppId>、<你的腾讯地图 Key>、<原生工程绝对路径>、<HarmonyOS 包名> 等,请替换为你自己的取值。
真实取值与内部落地细节以内部档案 OPENLOCATION_MAP_KEY_HARMONY.md 为准。

起因

一个"打开门店地图"的功能,在 Android/iOS 一直好好的,搬到 HarmonyOS Next 就只有一片空白,ArkWeb 控制台反复打印:

Map key not configured.

鸿蒙 Next 的地图只支持腾讯地图(高德在官方兼容表里被标为不支持),所以我们申请了腾讯 Key,写进了 manifest.json,重新编译、打包、真机运行 —— 依然空白。更诡异的是:后面反复"清缓存 + 重装"都不见效。

这篇文章记录最终定位到的真正原因,以及一个通用的"判断哪份脚本在真正执行"的排查手法。

第一层假象:配置写错地方了吗(确实错了,但还没到根上)

manifest.json 里给鸿蒙配腾讯 Key 的正确姿势是(注意字段名):

// src/manifest.json
"app-harmony": {
  "distribute": {
    "sdkConfigs": {
      "maps": {
        "tencent": { "key": "<你的腾讯地图 Key>" }   // 厂商名是 tencent、字段是 key,不是 qqmap
      }
    }
  }
}

两个易错点:

  1. 必须写在 app-harmony 下而不是 app-plus 下(鸿蒙构建时 UNI_PLATFORM=app-harmony,读取的是 manifest['app-harmony']);
  2. 厂商对象名是 tencent、键是 key,不是官方旧文档里写的 qqmap。

改完重新编译,产物 www/__uniappview.html 里确实注入了:

var __uniConfig = { ..., "qqMapKey": "<你的腾讯地图 Key>" }

但地图还是空白。 说明问题不在这一层。

关键排查手法:用"行号 vs 行数"判断真正执行的是哪份脚本

报错来自 uni-app-view.umd.js,控制台给出的行号是 23924。而我工程里同步进去的那份 uni-app-view.umd.js 是压缩版,整个文件才几行、约 35 万字节 —— 根本不可能有第 23924 行。

结论:控制台给的 source URL 和行号可能来自不同的文件副本。真正在跑的,是 SDK 依赖包里那份非压缩的 uni-app-view.umd.js(约 2.6 万行):

<原生工程绝对路径>/oh_modules/.ohpm/@dcloudio+uni-app-runtime@<hash>/oh_modules/@dcloudio/uni-app-runtime/src/main/resources/rawfile/uni-app/uni-app-view.umd.js

也就是说:我改 www、改 manifest,都影响不到这份真正在执行的非压缩副本。 这就是"怎么重装都不管用"的第一层原因。

经验:遇到"改了产物真机却没变化",先别急着怀疑缓存。把控制台堆栈里的行号和各份同名文件的实际行数做交叉比对,就能定位到底哪份代码在运行。

真正原因:新版 openLocation 的地图 key 来自原生 metadata

打开那份非压缩副本,发现新版取地图 key 的写法变了 —— 它不再直接读 __uniConfig.qqMapKey,而是调一个原生提供的服务方法 getMapConfig:

// view 层(非压缩副本)
invokeServiceMethod("getMapConfig", {}, (res) => {
  mapInfo = parseMapInfo(res);   // parseMapInfo 读的是 res.qqMapKey
});

而这个 getMapConfig 的原生实现(在 har 的 src/main/ets/uni-mp-sdk/sdk.js)是:

function getMapConfig() {
  const metadata = getEntryMetadata().find(d => d.name === "TENCENT_MAP_KEY");
  return { qqMapKey: metadata?.value };
}

getEntryMetadata() 读的是原生 module.json5 里的 metadata。 换句话说:新版运行时 openLocation 要的地图 key,来自原生工程清单的一条名为 TENCENT_MAP_KEY 的 metadata,而不是编译进前端 www 的 __uniConfig。

前端 key 只喂到了服务层,地图页压根不看那儿 —— 于是服务层有值 ≠ 地图有值。

解决:在原生 module.json5 补一条 metadata

<原生工程绝对路径>/entry/src/main/module.json5 的 module.metadata 里加一项:

metadata: [
    // ... 既有的其它 metadata 项 ...
    {
        name: "TENCENT_MAP_KEY",
        value: "<你的腾讯地图 Key>",
    },
],

因为这是 ArkTS 原生配置,必须卸载 App + Clean Project + 重装才生效(HarmonyOS 的 resfile/metadata 在增量 Run 时不会重新打进包里)。重装后,地图正常加载。

顺手解决的另外两件事

  1. 定位权限缺失:module.json5 的 requestPermissions 里没有定位权限,uni.getLocation 会报 maybe not obtain GPS Permission。补上 ohos.permission.APPROXIMATELY_LOCATION 与 ohos.permission.LOCATION(各带 reason 字符串资源与 usedScene)即可。
  2. 订单详情页乱弹定位:页面 onLoad 里为了算"门店距离"调了 uni.getLocation。补权限后,原本静默的失败变成了每次进页面弹系统授权框。产品上该页并不需要距离,于是去掉自动定位、把距离展示一并移除;定位只在真正进入地图时才由 openLocation 按需获取。

速查表

现象 根因 动作
Map key not configured.,改 manifest/重装都无效 新版 openLocation 从原生 module.json5 metadata.TENCENT_MAP_KEY 取 key 补该 metadata,Clean+重装
报错行号远超本地同名文件行数 真正执行的是 SDK 非压缩 rawfile 副本,不是同步进 www 的那份 别再改 www,转原生配置
只配 app-plus...maps.qqmap 无效 应为 app-harmony...maps.tencent.key 修正字段名与位置(但仍不足以出图)
getLocation:fail maybe not obtain GPS Permission 原生未声明定位权限 补 APPROXIMATELY_LOCATION/LOCATION
改了 www/权限真机无变化 增量 Run 不重打包 resfile/metadata 卸载 + Clean Project + 重装

一句话总结

鸿蒙新版运行时的 uni.openLocation 地图 key,认的是原生 module.json5 → metadata.TENCENT_MAP_KEY,而不是 manifest.json 编译进前端的那份。找到这条链路之前,所有的"重新编译打包"都是在错误的层打转。

posted on 2026-10-20 16:12  码间留白  阅读(18)  评论(0)    收藏  举报

导航