如何从Flutter应用中打开外部应用?含地图导航实现问询
要在Flutter里唤起第三方应用,最常用且靠谱的方案是用url_launcher插件——这是Flutter官方推荐的处理URL跳转、应用唤起的工具。下面是具体实现步骤:
1. 添加依赖
先在你的pubspec.yaml里加上插件依赖:
dependencies: url_launcher: ^6.2.5 # 记得用最新版本哦
然后运行flutter pub get把插件拉下来。
2. 平台权限配置
不同系统需要做一点小配置,不然可能唤起失败:
Android(11及以上)
在android/app/src/main/AndroidManifest.xml里添加查询外部应用的权限,比如你要打开微信,就加对应的包名:
<queries> <package android:name="com.tencent.mm" /> <!-- 微信的包名 --> <!-- 其他要唤起的应用包名也可以加在这里 --> </queries>
iOS
在ios/Runner/Info.plist里声明要调用的URL Scheme,还是以微信为例:
<key>LSApplicationQueriesSchemes</key> <array> <string>weixin</string> <!-- 微信的URL Scheme --> </array>
3. 代码示例
比如写个方法唤起微信:
import 'package:url_launcher/url_launcher.dart'; Future<void> openWeChat() async { const weChatUrl = 'weixin://'; // 微信的URL Scheme final uri = Uri.parse(weChatUrl); if (await canLaunchUrl(uri)) { await launchUrl(uri); } else { // 这里可以给用户弹个提示,比如“未安装微信” throw '无法打开微信,请检查是否已安装应用'; } }
💡 小提示:不同应用的URL Scheme需要提前确认,比如淘宝是taobao://,支付宝是alipay://。不确定的话可以查应用官方的开发者文档,或者去开发者社区搜一下。
这个需求有两种主流实现方式,看你想要的体验来选:
方案一:用url_launcher唤起系统默认地图
用Geo URI这种跨平台标准格式,能直接唤起系统默认的地图应用(比如Android的谷歌/百度地图,iOS的Apple Maps),还能直接发起导航:
import 'package:url_launcher/url_launcher.dart'; Future<void> startNavigation(double targetLat, double targetLng, String targetAddress) async { // Geo URI格式:geo:纬度,经度?q=目标地址(用于导航定位) final navigationUri = Uri.parse('geo:$targetLat,$targetLng?q=$targetAddress'); if (await canLaunchUrl(navigationUri)) { await launchUrl(navigationUri); } else { throw '无法打开地图应用,请检查是否已安装'; } }
调用的时候传入目标地点的经纬度和地址就行,系统会自动处理剩下的步骤。
方案二:用map_launcher插件让用户选择地图应用
如果你想让用户自己选打开谷歌地图、高德、百度还是其他地图,那map_launcher插件就很合适——它能检测设备上已安装的地图应用,还能直接唤起对应应用的导航界面。
步骤1:添加依赖
dependencies: map_launcher: ^3.2.0 # 同样用最新版本
步骤2:代码示例
写个方法弹出底部菜单让用户选地图:
import 'package:map_launcher/map_launcher.dart'; import 'package:flutter/material.dart'; Future<void> showMapChoiceBottomSheet(BuildContext context, double lat, double lng, String placeTitle) async { // 获取设备上已安装的所有地图应用 final availableMaps = await MapLauncher.installedMaps; if (availableMaps.isEmpty) { // 提示用户未安装任何地图应用 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('未安装任何地图应用')), ); return; } // 弹出底部选择菜单 await showModalBottomSheet( context: context, builder: (context) => SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: availableMaps.map((map) { return ListTile( leading: Image(image: map.icon, height: 30, width: 30), title: Text(map.mapName), onTap: () { Navigator.pop(context); // 唤起该地图的导航界面 map.showDirections( destination: Coords(lat, lng), destinationTitle: placeTitle, ); }, ); }).toList(), ), ), ); }
这个方案用户体验更好,毕竟不同用户习惯用不同的地图应用。
总结一下:如果追求轻量快速,选url_launcher;如果要支持多地图选择,选map_launcher就对了。
内容的提问来源于stack exchange,提问作者Ghanshyam Savaliya

