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
}
}
}
}
两个易错点:
- 必须写在
app-harmony下而不是app-plus下(鸿蒙构建时UNI_PLATFORM=app-harmony,读取的是manifest['app-harmony']); - 厂商对象名是
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 时不会重新打进包里)。重装后,地图正常加载。
顺手解决的另外两件事
- 定位权限缺失:
module.json5的requestPermissions里没有定位权限,uni.getLocation会报maybe not obtain GPS Permission。补上ohos.permission.APPROXIMATELY_LOCATION与ohos.permission.LOCATION(各带reason字符串资源与usedScene)即可。 - 订单详情页乱弹定位:页面
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 编译进前端的那份。找到这条链路之前,所有的"重新编译打包"都是在错误的层打转。
浙公网安备 33010602011771号