在鴻蒙應用開發中,經常需要跳轉第三方地圖應用(如 騰訊地圖、百度地圖、高德地圖)進行導航。無論是出行類 App、物流類 App,還是線下活動類應用,都存在“跳轉地圖導航”的實際需求。寫完HarmonyOS應用拉起系列一和二后在鴻蒙開發者社區以及各類技術問答平臺上很多開發者都在詢問:如何實現直接拉起導航應用。本文結合拉起系列一和實戰代碼,講解如何封裝 MapNavigator 工具類,實現:
- 判斷地圖應用是否安裝
通過 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 中提出,我們將持續優化并補充更多地圖應用和導航參數的支持。如果大家喜歡或者對這個系列感興趣歡迎大家在評論區交流討論。
望一鍵三連!
六、代碼倉庫
README.md · ZhangHuiXin/MapNavigatorDemo - Gitee.com