给鸿蒙 App 增加一键唤起地图导航的能力 —— maps_launcher 的鸿蒙使用指南
给鸿蒙 App 增加一键唤起地图导航的能力 —— maps_launcher 的鸿蒙使用指南
本文配套仓库:https://atomgit.com/oh-flutter/maps_launcher(TAG:
3.0.0-ohos-1.0.0-beta.1,分支:feat/ohos_maps_launcher_3.0.0),文中示例代码位于仓库example/目录。
把用户从应用内一步带到地图应用,是线下门店、外卖配送、出行类应用的高频需求:搜一个地点、看一处坐标、唤起导航。鸿蒙应用同样需要这个能力。本文介绍如何使用鸿蒙化适配后的 Flutter 三方库 maps_launcher,用两个静态方法在鸿蒙 App 内拉起系统导航应用选择面板,由用户在已安装的地图应用中直接选择,并附上 HUAWEI nova 12 Ultra 真机的完整实测记录。
一、最终运行效果
应用启动后输入地点关键词,点击 launchQuery:搜索地点 按钮,系统弹出导航应用选择面板,选择花瓣地图直达搜索结果:
| 验证点 | 结果 |
|---|---|
| 应用启动,Flutter 页面正常渲染 | 通过 |
| 点击 launchQuery 按钮,系统弹出导航应用选择面板 | 通过 |
| 面板中选择花瓣地图,正常进入其搜索结果页 | 通过 |
| 点击 launchCoordinates 按钮,系统提示"暂无可用导航方式",返回 true | 符合预期(见 FAQ Q1) |

图一:demo 应用在 HUAWEI nova 12 Ultra 真机启动(HarmonyOS 6.1.0 / API 24)

图二:点击 launchQuery 后系统弹出导航应用选择面板,列出设备上已安装的地图应用

图三:在面板中选择花瓣地图,直达"上海东方明珠"的搜索结果页
检查要点:
- 导航应用选择面板由系统
startAbilityByType('navigation')弹出,属于系统能力,插件与业务方都无需申请任何权限;- 面板中出现哪些应用,由各地图应用自身声明的 linkFeature 决定(详见"七、工作原理"与 FAQ Q1);
- 完整实测过程见"六、运行与验证"。
二、maps_launcher 是什么
maps_launcher 原库(pub.dev 3.0.0+1,作者 pikaju)是一个打开设备上地图应用的 Flutter 插件,支持按名称搜索地点与按坐标展示目的地。鸿蒙适配版在其基础上新增了 OpenHarmony / HarmonyOS 平台支持:拉起系统导航应用选择面板,由用户选择导航应用。
几个对使用者友好的特点:
- 零权限:面板由系统能力拉起,不需要在 module.json5 中申请任何权限;
- 不绑定单一地图:不像深链方案把用户固定在某个地图 App,而是由系统列出设备上已安装的地图应用,交给用户选择;
- 跨平台一套代码:Android、iOS、鸿蒙、桌面与 Web 共用同一对接口,运行在哪端就按哪端的方式打开地图。
接口说明:
| 名称 | 描述 | 类型 | 参数类型 | 返回值 | 必填 | 鸿蒙平台支持 |
|---|---|---|---|---|---|---|
| MapsLauncher.launchQuery | 打开地图应用并展示搜索结果 | method | query: String | Future<bool> | 是 | 是 |
| MapsLauncher.launchCoordinates | 打开地图应用并展示指定坐标 | method | latitude: double, longitude: double, [label: String?] | Future<bool> | 是 | 是 |
三、环境准备
本文所有实测均在以下环境完成:
| 项 | 版本 | 说明 |
|---|---|---|
| Flutter(ohos 版) | 3.41.10-ohos-1.0.1 | 主验证环境,真机实测 |
| 编译 SDK | 6.1.0(23) | 宿主工程 compatibleSdkVersion 同值,保留带括号的旧格式 |
| 真机 | HUAWEI nova 12 Ultra(ADA-AL10) | HarmonyOS 6.1.0.135 / API 24,分辨率 1224 × 2776 |
两点提醒:
- 编译鸿蒙目标需要使用 ohos 版 Flutter SDK,普通 Flutter SDK 无法编译 ohos 产物;
- 若在真机上安装应用报"此应用暂不支持在当前设备安装",是宿主工程的
compatibleSdkVersion高于设备 API 导致的,与插件无关,处理方式见 FAQ Q4。
四、引入依赖
进入工程目录,在 pubspec.yaml 中添加 git 依赖:
dependencies:
maps_launcher:
git:
url: https://atomgit.com/oh-flutter/maps_launcher.git
# ref: 根据下方表格选择不同框架适配的 TAG 版本
ref: 3.0.0-ohos-1.0.0-beta.1
执行命令拉取依赖:
flutter pub get
TAG 命名规则:原库版本-ohos-版本号-beta.x。
| Flutter 框架版本 | TAG 名称 | 分支名 |
|---|---|---|
| 3.44 | 3.0.0-ohos-1.0.0-beta.1 | feat/ohos_maps_launcher_3.0.0 |
说明:该 TAG 已在 3.41 系 stable(
3.41.10-ohos-1.0.1)真机上实测通过,3.41 用户可直接使用;3.44 canary 引擎的 ArkTS 层要求 API 26,需将宿主工程compatibleSdkVersion调整为26.0.0(见 FAQ Q5)。
五、代码接入
5.1 导入库
import 'package:maps_launcher/maps_launcher.dart';
5.2 按名称搜索地点
final ok = await MapsLauncher.launchQuery('上海东方明珠');
query 是自由文本,地点名称或地址均可。在鸿蒙设备上,它作为目的地搜索文本进入系统导航面板,用户选择某个地图应用后即看到对应的搜索结果。
5.3 展示指定坐标
final ok = await MapsLauncher.launchCoordinates(31.239717, 121.499876, '上海陆家嘴');
latitude 与 longitude 为必填的经纬度,可选参数 label 作为目的地名称展示。
坐标系提醒:鸿蒙导航面板在中国大陆要求 GCJ-02 坐标系,而原库未对输入坐标系作约定(实际通常为 WGS-84)。在中国大陆启动坐标导航前,建议先完成 WGS-84 到 GCJ-02 的转换,避免数百米级的偏差;中国大陆以外的坐标将原样透传(详见 FAQ Q3)。
5.4 跨平台一套代码
同一对接口在各端的行为:
| 平台 | 行为 |
|---|---|
| Android | 打开匹配 geo: URI 的地图应用 |
| iOS | 打开 Apple Maps |
| OpenHarmony / HarmonyOS | 拉起系统导航应用选择面板,由用户选择导航应用 |
| 桌面端与 Web | 通过浏览器打开 Google Maps |
两个方法在拉起成功时返回 true,失败时返回 false。
5.5 实战:给门店详情页加一个"导航到这里"按钮
实际业务中常见的场景是门店、餐厅、网点的详情页放一个常驻的"导航到这里"按钮。下面是一个可直接使用的组件:
import 'package:flutter/material.dart';
import 'package:maps_launcher/maps_launcher.dart';
class NavigateButton extends StatelessWidget {
const NavigateButton({
super.key,
required this.latitude,
required this.longitude,
this.label,
});
final double latitude;
final double longitude;
final String? label;
Widget build(BuildContext context) {
return FilledButton.icon(
icon: const Icon(Icons.navigation),
label: const Text('导航到这里'),
onPressed: () async {
final ok = await MapsLauncher.launchCoordinates(latitude, longitude, label);
if (!context.mounted || ok) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('未找到可用的地图应用,请先安装')),
);
},
);
}
}
面板未拉起、设备上没有可用地图应用时返回 false,业务可据此降级提示;返回值的完整语义见 FAQ Q2。
六、运行与验证
以下为 demo 工程的真机实测记录。仓库中 example 的 Bundle Name 为 com.example.example;本轮测试时签名配置临时使用了包名 com.example.demo,仅影响安装包标识、不影响功能验证,仓库已还原为 com.example.example。
| 设备项 | 值 |
|---|---|
| 机型 | HUAWEI nova 12 Ultra(ADA-AL10) |
| 系统版本 | HarmonyOS 6.1.0.135(SP8C00E120R2P6) |
| API 版本 | 24 |
| 分辨率 | 1224 × 2776 |
6.1 验证一:launchQuery 位置搜索
安装、启动 demo 并模拟点击:
# 构建 hap 后安装(真机安装对 SDK 版本有要求,见 FAQ Q4)
hdc install entry-default-signed.hap
# 启动 demo
hdc shell aa start -b com.example.demo -a EntryAbility
# 模拟点击 launchQuery 按钮(坐标按实际设备与页面布局调整)
hdc shell uitest uiInput click 611 1227
# 在弹出的系统面板中选择花瓣地图
hdc shell uitest uiInput click 611 2249
实测现象与图一、图二、图三一致:Flutter 页面正常渲染;点击 launchQuery 后系统弹出导航应用选择面板,列出设备上已安装的地图应用;选择花瓣地图后正常进入"上海东方明珠"的搜索结果页。
6.2 验证二:launchCoordinates 地点详情
重新拉起 demo,模拟点击坐标按钮:
# 重新启动 demo
hdc shell aa start -b com.example.demo -a EntryAbility
# 模拟点击 launchCoordinates 按钮
hdc shell uitest uiInput click 611 1807

图四:点击 launchCoordinates 后系统提示"暂无可用导航方式",设备上的地图应用均未声明 DetailLocation 能力,面板无可选应用
系统提示"暂无可用导航方式",而接口返回值为 true:拉起动作本身已由系统完成,只是面板内没有声明 DetailLocation 能力的应用可选。这是设备应用生态的现状,不是插件缺陷,机制解释见 FAQ Q1。
实测结论:
| 验证点 | 结果 |
|---|---|
| 应用启动,Flutter 页面正常渲染 | 通过 |
| 点击 launchQuery,系统弹出导航应用选择面板 | 通过 |
| 面板中选择花瓣地图,正常进入其搜索结果页 | 通过 |
| 点击 launchCoordinates,系统提示"暂无可用导航方式",返回 true | 符合预期(见 FAQ Q1) |
| 全程无需申请任何权限 | 通过 |
七、工作原理
整个调用链路如下:
Dart: MapsLauncher.launchQuery / launchCoordinates
→ MethodChannel('maps_launcher')
→ ArkTS: MapsLauncherPlugin.onMethodCall
→ 组装 wantParam 并 startAbilityByType('navigation')
→ 系统弹出导航应用选择面板
Dart 侧通过 Platform.operatingSystem == 'ohos' 识别鸿蒙平台:鸿蒙上走 MethodChannel 调用原生插件,其余平台沿用原库的 url_launcher 逻辑。
鸿蒙侧通过 startAbilityByType('navigation') 的 sceneType 区分场景:
| sceneType | 场景 | 必填参数 | 对应接口 |
|---|---|---|---|
| 3 | 位置搜索 | destinationName | launchQuery |
| 4 | 地点详情 | destinationLatitude、destinationLongitude | launchCoordinates |
系统还定义了路线规划(sceneType 1)与导航(sceneType 2)等场景,当前适配未覆盖,欢迎扩展(见 FAQ Q6)。
鸿蒙侧插件实现(ArkTS)核心有两段。一段是按接口组装 wantParam,以 launchQuery 为例:
case 'launchQuery': {
const query: string | undefined = call.argument('query');
// 位置搜索场景(sceneType: 3):destinationName 为搜索关键字(必填)
const wantParam: Record<string, Object> = {
'sceneType': 3,
'destinationName': query
};
this.startNavigationAbility(wantParam, result);
break;
}
另一段是发起拉起并回传结果。MethodResult 只允许回复一次,而 startAbilityByType 的异步回调(onError/onResult)与同步 AsyncCallback 可能先后触发,replyOnce 保证 Future<bool> 恰好 resolve 一次:
let replied: boolean = false;
const replyOnce = (value: boolean): void => {
if (!replied) { replied = true; result.success(value); }
};
const abilityStartCallback: common.AbilityStartCallback = {
onError: (code: number, name: string, message: string) => { replyOnce(false); },
onResult: (abilityResult: common.AbilityResult) => { replyOnce(true); }
};
try {
context.startAbilityByType('navigation', wantParam, abilityStartCallback, (err: BusinessError) => {
if (err) { replyOnce(false); } else { replyOnce(true); }
});
} catch (err) { replyOnce(false); }
面板中出现哪些应用,由各地图应用在自身 module.json5 的 skills.uris 中声明的 linkFeature 决定(Navigation、RoutePlan、PlaceSearch、DetailLocation 四类)。实测设备上已安装的地图应用均声明了 PlaceSearch,因此 launchQuery 的面板能正常列出它们;但均未声明 DetailLocation,launchCoordinates 便提示"暂无可用导航方式"。
八、常见问题
Q1:launchCoordinates 提示"暂无可用导航方式"是怎么回事?
面板内可选哪些应用由各地图应用声明的 linkFeature 决定。实测设备上的地图应用只声明了 PlaceSearch(位置搜索)能力,未声明 DetailLocation(地点详情)能力,所以搜索场景一切正常、坐标详情场景没有可选应用。此时拉起动作本身已完成,接口返回 true。随着地图应用逐步补齐 linkFeature 声明,该场景会自然可用。
Q2:返回 true 就代表地图应用被打开了吗?
true 表示"拉起动作成功完成"(系统回调确认),不保证面板里有应用可选,也不代表某个具体地图应用完成了展示。对可用性敏感的业务,建议结合自身目标场景做功能实测(参考 Q1)。
Q3:中国大陆的坐标为什么偏了几百米?
坐标系问题。鸿蒙导航面板在中国大陆要求 GCJ-02,而多数业务数据(尤其来自 GPS 或国际地图服务)是 WGS-84。在中国大陆启动坐标导航前先做 WGS-84 到 GCJ-02 的转换;中国大陆以外的坐标原样透传即可。
Q4:真机安装 demo 时提示"此应用暂不支持在当前设备安装"?
这是宿主工程的 compatibleSdkVersion 高于真机 API 版本导致的安装校验失败,与插件无关。将 compatibleSdkVersion 调整为不高于真机 API 的版本(如 6.1.0(23),注意保留带括号的旧格式)即可。本文配套仓库的 example 已用此配置在 nova 12 Ultra(API 24)上安装实测通过。
Q5:用 3.44 canary 构建时报 API 版本错误?
3.44 canary 引擎的 ArkTS 层要求 API 26,需将宿主工程 compatibleSdkVersion 改为 26.0.0。本文实测使用的 3.41.10-ohos-1.0.1 搭配 6.1.0(23) 即可在 API 24 真机运行。
Q6:想直接拉起路线规划或导航怎么办?
系统面板还定义了路线规划(sceneType 1)与导航(sceneType 2)等场景,当前适配覆盖位置搜索与地点详情两类。如业务需要,可参考"七、工作原理"扩展 wantParam,欢迎提 PR 共建。
九、结语
回顾一下:在 pubspec.yaml 中以 git TAG 引入 maps_launcher,调用 MapsLauncher.launchQuery() 或 MapsLauncher.launchCoordinates() 两个静态方法,即可在鸿蒙 App 内把用户带进地图应用:搜索场景由系统面板列出已安装的地图应用,用户一键直达;同一段代码在 Android、iOS、桌面与 Web 上也各自生效。插件零权限、不绑定单一地图,已在 nova 12 Ultra 真机(HarmonyOS 6.1.0 / API 24)完整实测。
使用中发现任何问题,欢迎到配套仓库提 Issue,也欢迎发 PR 共建。
相关链接
欢迎加入 CPF-Flutter 鸿蒙社区,社区入口、环境搭建指南和本文相关链接统一放在这里:
更多推荐



所有评论(0)