HarmonyOS鸿蒙Next中如何在应用内直接拉起腾讯/百度/高德地图进行导航
HarmonyOS鸿蒙Next中如何在应用内直接拉起腾讯/百度/高德地图进行导航 如何在应用内直接拉起腾讯/百度/高德地图进行导航
导航类应用扩展面板参数说明
startAbilityByType接口中type字段为navigation,支持路线规划、导航、位置搜索三种意图场景,对应的wantParam参数如下:
说明
本文中的经纬度均采用GCJ-02坐标系统。
- 路线规划场景
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| sceneType | number | 否 | 意图场景,表明本次请求对应的操作意图。默认为1,路线规划场景填1或不填。 |
| originName | string | 否 | 起点名称。 |
| originLatitude | number | 否 | 起点纬度。 |
| originLongitude | number | 否 | 起点经度。 |
| originPoiIds | Record<number, string> | 否 | 起点POI ID列表,当前仅支持传入花瓣地图、高德地图、百度地图的POI ID。 |
| destinationName | string | 否 | 终点名称。 |
| destinationLatitude | number | 是 | 终点纬度。 |
| destinationLongitude | number | 是 | 终点经度。 |
| destinationPoiIds | Record<number, string> | 否 | 终点POI ID列表,当前仅支持传入花瓣地图、高德地图、百度地图的POI ID。 |
| vehicleType | number | 否 | 交通出行工具,取值:0-驾车,1-步行,2-骑行,3-公交。 |
- 导航场景
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| sceneType | number | 是 | 意图场景,表明本次请求对应的操作意图。导航场景填2。 |
| destinationName | string | 否 | 终点名称。 |
| destinationLatitude | number | 是 | 终点纬度。 |
| destinationLongitude | number | 是 | 终点经度。 |
| destinationPoiIds | Record<number, string> | 否 | 终点POI ID列表,当前仅支持传入花瓣地图、高德地图、百度地图的POI ID。 |
- 位置搜索场景
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| sceneType | number | 是 | 意图场景,表明本次请求对应的操作意图。位置搜索场景填3。 |
| destinationName | string | 是 | 地点名称。 |
直接上代码:
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
const TAG = 'EntryAbility';
export default class EntryAbility extends UIAbility {
windowStage: window.WindowStage | null = null;
uri?: string;
destinationLatitude?: number;
destinationLongitude?: number;
destinationName?: string;
originName?: string;
originLatitude?: number;
originLongitude?: number;
vehicleType?: number;
destinationPoiId?: string;
originPoiId?: string;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, TAG, `onCreate, want=${JSON.stringify(want)}`);
super.onCreate(want, launchParam);
this.parseWant(want);
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, TAG, `onNewWant, want=${JSON.stringify(want)}`);
super.onNewWant(want, launchParam);
this.parseWant(want);
if (!this.windowStage) {
hilog.error(0x0000, TAG, 'windowStage is null');
this.context.terminateSelf();
return;
}
this.loadPage(this.windowStage);
}
private parseWant(want: Want): void {
this.uri = want.uri as string | undefined;
this.destinationLatitude = want.parameters?.destinationLatitude as number | undefined;
this.destinationLongitude = want.parameters?.destinationLongitude as number | undefined;
this.destinationName = want.parameters?.destinationName as string | undefined;
this.originName = want.parameters?.originName as string | undefined;
this.originLatitude = want.parameters?.originLatitude as number | undefined;
this.originLongitude = want.parameters?.originLongitude as number | undefined;
this.vehicleType = want.parameters?.vehicleType as number | undefined;
this.destinationPoiId = want.parameters?.destinationPoiId as string | undefined;
this.originPoiId = want.parameters?.originPoiId as string | undefined;
}
private loadPage(windowStage: window.WindowStage): void {
hilog.info(0x0000, TAG, `loadPage, uri=${this.uri}`);
if (this.uri === 'maps://navigation') {
// 构建导航场景参数
const storage: LocalStorage = new LocalStorage({
"destinationLatitude": this.destinationLatitude,
"destinationLongitude": this.destinationLongitude,
"destinationPoiId": this.destinationPoiId
} as Record<string, Object>);
// 拉起导航页面
windowStage.loadContent('pages/NavigationPage', storage)
} else if (this.uri === 'maps://routePlan') {
// 构建路径规划场景参数
const storage: LocalStorage = new LocalStorage({
"destinationLatitude": this.destinationLatitude,
"destinationLongitude": this.destinationLongitude,
"destinationName": this.destinationName,
"originName": this.originName,
"originLatitude": this.originLatitude,
"originLongitude": this.originLongitude,
"vehicleType": this.vehicleType,
"destinationPoiId": this.destinationPoiId,
"originPoiId": this.originPoiId
} as Record<string, Object>);
// 拉起路径规划页面
windowStage.loadContent('pages/RoutePlanPage', storage)
} else if (this.uri === 'maps://search') {
// 构建位置搜索场景参数
const storage: LocalStorage = new LocalStorage({
"destinationName": this.destinationName
} as Record<string, Object>);
// 拉起位置搜索页面
windowStage.loadContent('pages/PlaceSearchPage', storage)
} else {
// 默认拉起首页
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, TAG, 'Failed to load the content. Cause: %{public}s',
JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, TAG, 'Succeeded in loading the content.');
});
}
}
onDestroy(): void {
hilog.info(0x0000, TAG, `onDestroy`);
}
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(0x0000, TAG, `onWindowStageCreate`);
this.windowStage = windowStage;
this.loadPage(this.windowStage);
}
onWindowStageDestroy(): void {
hilog.info(0x0000, TAG, '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
hilog.info(0x0000, TAG, '%{public}s', 'Ability onForeground');
}
onBackground(): void {
hilog.info(0x0000, TAG, '%{public}s', 'Ability onBackground');
}
}
更多关于HarmonyOS鸿蒙Next中如何在应用内直接拉起腾讯/百度/高德地图进行导航的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
找相关APP的SDK,
【实现思路】
- 判断地图应用是否安装 通过 scheme 检查(如
qqmap://、baidumap://、amapuri://),在拉起地图前先判断 App 是否存在,避免跳转失败。需要注意,这些 scheme 必须在module.json5的querySchemes字段中声明,否则canOpenLink会返回错误或不准确的结果。 - 拉起导航(startAbility 与 openLink 两种方式)
startAbilityByWant:通过构建Want对象携带导航参数,包括起点名称、起点经纬度、终点名称、终点经纬度、导航模式(驾车、步行、公交等)等,精确传递给第三方地图 App。openLink:通过 URL scheme 拼接导航参数,直接拉起地图应用进行导航,同样支持传递起终点坐标、路线偏好等信息。- 未安装提示逻辑 如果检测到地图 App 未安装,统一调用提示方法(如
promptAction.showToast)告知用户“腾讯地图/百度地图/高德地图未安装”,同时可扩展为引导用户前往应用市场下载。 - querySchemes 配置的重要性 只有在
module.json5中声明了对应的 scheme,鸿蒙系统才能正确识别并允许通过canOpenLink或 openLink 拉起第三方 App,否则即便 App 已安装,也会出现“暂无打开方式”的提示。
通过封装,开发者只需调用相应方法并传入 起点、终点名称与经纬度,就能轻松实现多地图导航功能,避免重复实现安装判断、参数拼接和异常处理逻辑。
一、前提:querySchemes 配置
在鸿蒙中,判断应用是否安装通常依赖 bundleManager.canOpenLink(scheme)。必须在自己应用的 module.json5 中配置对应的 scheme,否则即使应用安装了,也可能返回 false。
示例配置:
"module": {
"querySchemes": [
"qqmap",
"baidumap",
"amapuri"
]
}
- 这里的
qqmap,baidumap,amapuri对应三方地图的 scheme。 - 仅被拉起的应用需要配置自己的 URI;自己的应用只需配置 querySchemes。
配置错误是
canOpenLink返回 false 的常见原因。
二、工具类设计思路
封装思路:
- 定义 包名 与 scheme:
export enum MapApp {
TENCENT = 'com.tencent.mapohos',
BAIDU = 'com.baidu.hmmap',
AMAP = 'com.amap.hmapp'
}
export enum MapScheme {
TENCENT = 'qqmap://',
BAIDU = 'baidumap://',
AMAP = 'amapuri://'
}
- 提供两类拉起方式:
- startAbility 方式:可以传递完整参数,并可用于鸿蒙应用或元服务。
- openLink 方式:类似 URI Scheme 方式,调用简单,直接拉起第三方应用。
- 判断安装,未安装统一提示。
三、方法拆解讲解
1. 判断应用是否安装
private isMapInstalled(scheme: string): boolean {
try {
return bundleManager.canOpenLink(scheme);
} catch (err) {
console.error(`canOpenLink failed for ${scheme}`, JSON.stringify(err));
return false;
}
}
- 原理:通过 scheme 查询应用是否能被打开。
- 注意:必须在
querySchemes中声明,否则返回 false。 - 示例:
if (!this.isMapInstalled(MapScheme.TENCENT)) {
this.showNotInstalledMsg('腾讯地图');
}
2. startAbility 方式拉起导航
async openTencentMapByWant(from: string, fromLat: number, fromLng: number,
to: string, toLat: number, toLng: number) {
if (!this.isMapInstalled(MapScheme.TENCENT)) {
this.showNotInstalledMsg('腾讯地图');
return;
}
const want: Want = {
action: 'ohos.want.action.viewData',
uri: `qqmap://map/routeplan?type=drive` +
`&from=${from}&fromcoord=${fromLat},${fromLng}` +
`&to=${to}&tocoord=${toLat},${toLng}` +
`&policy=0&referer=myApp`
};
this.openMethod.startAbilityByWant(want);
}
- 适用场景:希望完整控制参数、或者拉起鸿蒙应用/元服务。
- 优点:可捕获异常,便于处理未安装或其他错误。
注意:百度地图在鸿蒙上暂时不支持
canOpenLink判断,可直接尝试拉起。
3.openLink 方式拉起导航
async openTencentMapByLink(from: string, fromLat: number, fromLng: number,
to: string, toLat: number, toLng: number) {
if (!this.isMapInstalled(MapScheme.TENCENT)) {
this.showNotInstalledMsg('腾讯地图');
return;
}
const url = `qqmap://map/routeplan?type=drive` +
`&from=${from}&fromcoord=${fromLat},${fromLng}` +
`&to=${to}&tocoord=${toLat},${toLng}` +
`&policy=0&referer=myApp`;
this.openMethod.openLink(url);
}
- 适用场景:快速拉起第三方应用。
- 优点:无需关心包名和 Ability 名称。
- 注意:需要保证 scheme 配置正确,否则会出现“暂无打开方式”。
4.统一未安装提示
private showNotInstalledMsg(appName: string) {
promptAction.showToast({ message: `${appName} 未安装` });
}
- 思路:所有地图统一调用该方法提示。
- 可进一步引导用户前往应用市场下载。
四、使用示例
// 拉起腾讯地图导航
Button('拉起腾讯地图-ByLink').onClick((event: ClickEvent) => {
this.mapNavigator.openTencentMapByLink('我的位置', 39.908823, 116.397470, '天安门', 39.915156, 116.403694)
})
// 拉起百度地图导航
Button('拉起百度地图-ByLink').onClick((event: ClickEvent) => {
this.mapNavigator.openBaiduMapByLink('我的位置', 39.908823, 116.397470, '天安门', 39.915156, 116.403694)
})
// 拉起高德地图导航
Button('拉起高德打车-ByLink').onClick((event: ClickEvent) => {
this.mapNavigator.openAmapByLink('我的位置', 39.908823, 116.397470, '天安门', 39.915156, 116.403694)
})
// 拉起腾讯地图导航
Button('拉起腾讯地图-ByWant').onClick((event: ClickEvent) => {
this.mapNavigator.openTencentMapByWant('我的位置', 39.908823, 116.397470, '天安门', 39.915156, 116.403694)
})
// 拉起百度地图导航
Button('拉起百度地图-ByWant').onClick((event: ClickEvent) => {
this.mapNavigator.openBaiduMapByWant('我的位置', 39.908823, 116.397470, '天安门', 39.915156, 116.403694)
})
// 拉起高德地图导航
Button('拉起高德打车-ByWant').onClick((event: ClickEvent) => {
this.mapNavigator.openAmapByWant('我的位置', 39.908823, 116.397470, '天安门', 39.915156, 116.403694)
})
五、总结与最佳实践
- querySchemes 配置至关重要,否则
canOpenLink失效。 - startAbility 与 openLink 方法各有优势:
- startAbility :可传递参数,可拉起鸿蒙应用/元服务
- openLink:轻量、简单,适合第三方应用
- 统一未安装提示,提升用户体验。
- 百度地图在鸿蒙上 安装检测存在限制,直接拉起即可,异常捕获处理即可。
通过这种封装方式,业务逻辑只需关注 起点、终点,不必关心每个地图应用的调用差异,极大提高了开发效率与可维护性,以上示例代码和封装逻辑已在 真机上 测试通过,如有异常或适配问题,欢迎大家在 Issues 中提出,我们将持续优化并补充更多地图应用和导航参数的支持。如果大家喜欢或者对这个系列感兴趣欢迎大家在评论区交流讨论。
望一键三连!
六、代码仓库
在HarmonyOS Next中,可通过want参数调用地图应用。使用startAbility方法,指定地图应用的bundleName和abilityName,并在parameters中传入目的地坐标或地址信息。需提前在module.json5中声明所需权限,如ohos.permission.LOCATION。具体参数格式需参考对应地图厂商提供的鸿蒙SDK文档。
在HarmonyOS Next中,应用内拉起第三方地图应用(如腾讯、百度、高德地图)进行导航,主要通过HarmonyOS的Want和隐式启动能力实现。核心步骤是构造一个符合目标地图应用约定的意图(Want),并启动对应的Ability。
以下是关键实现方法:
-
确认目标地图应用的支持情况:首先需在设备上安装对应的地图应用,并确认其支持通过HarmonyOS Want被拉起。通常主流地图应用会提供相关的协议或文档。
-
构造Want对象:这是最关键的一步。你需要根据各地图应用公开的URI格式或action来构造Want,以传递目的地参数(如经纬度、地名)。
- 基本参数:通常包括
action(如"ohos.want.action.viewData")和uri(或entities、parameters)。 - URI示例格式(具体格式需查阅对应地图厂商的HarmonyOS适配文档或参考其Android协议进行类比):
- 高德地图:
"location://com.amap.location?lat=39.904989&lon=116.405285&name=目的地" - 百度地图:
"bdapp://map/navi?destination=纬度,经度|地名" - 腾讯地图:
"qqmap://map/routeplan?type=drive&to=目的地&tocoord=纬度,经度"
- 高德地图:
- 在Want的
parameters中也可以传递键值对参数。
- 基本参数:通常包括
-
使用隐式Want启动:通过
startAbility()方法,并设置Want的action、uri、entities等属性,系统会匹配并让用户选择已安装的、能处理该意图的地图应用。import { common, Want } from '@kit.AbilityKit'; let wantInfo: Want = { action: 'ohos.want.action.viewData', // 常用查看数据的action // 示例:拉起高德地图导航到北京 uri: 'location://com.amap.location?lat=39.904989&lon=116.405285&name=天安门', // 或使用parameters传递参数 // parameters: { // 'lat': 39.904989, // 'lon': 116.405285, // 'name': '天安门' // } }; let context = getContext(this) as common.UIAbilityContext; context.startAbility(wantInfo).then(() => { // 成功拉起 }).catch((err) => { // 处理错误,如未安装对应应用 }); -
处理未安装应用的情况:如果设备未安装目标地图应用,
startAbility可能会失败。为了更好的用户体验,建议:- 在调用前,可以使用
abilityManager.getAbilityList()查询设备上已安装的应用,判断是否存在能处理对应Want的应用。 - 或者捕获启动失败的错误,引导用户跳转到AppGallery安装所需地图应用。
- 在调用前,可以使用
注意事项:
- 参数格式:各地图应用所需的URI或参数键值对格式可能不同,且可能随版本更新而变化。最准确的方式是查阅该地图应用为HarmonyOS Next提供的官方开发文档或接口说明。
- 权限:通常拉起导航不需要特殊权限,但如果你的应用需要获取用户当前位置作为起点,则需要申请相应的位置权限(
ohos.permission.LOCATION)。 - 多应用选择:当多个地图应用都能响应同一个Want时,系统会弹出选择器让用户选择。你可以通过设置
Want的entities字段来更精确地匹配特定应用。
由于HarmonyOS Next处于快速发展阶段,建议在实际开发时,优先查询华为官方文档中关于Want和隐式启动的详细说明,并关注目标地图应用厂商是否发布了针对HarmonyOS Next的导航拉起规范。

