Flutter - APP跳转高德、百度、腾讯、谷歌地图
demo 地址: https://github.com/iotjin/jh_flutter_demo
代码不定时更新,请前往github查看最新代码
这里介绍的是不需要自己开发地图,直接通过给定的经纬度,跳转到三方地图APP调用导航的方式
一种是写的工具类,一种是通过调用三方库map_launcher实现的
官方文档:
-
跳转高德导航 - 路径规划
高德地图官方文档 - Android
高德地图官方文档 - iOS -
跳转高德导航
高德地图官方文档 -
跳转百度导航 - 路径规划
百度地图官方文档 -
跳转腾讯导航
腾讯地图官方文档
参考文章:
Flutter 跳转地图软件调起导航:百度、高德、腾讯、苹果
Flutter 实战调起三方地图导航(高德、百度、腾讯、苹果)
插件:
map_launcher
flutter_map
maps_launcher
实现
在 pubspec.yaml 文件中添加依赖插件:
# url打开工具 https://pub.flutter-io.cn/packages/url_launcherurl_launcher: ^6.1.14# 打开地图工具 https://pub.flutter-io.cn/packages/map_launchermap_launcher: ^2.5.0+1
示例demo
/// map_jump_test_page.dart
///
/// Created by iotjin on 2023/10/16.
/// description: 跳转三方地图APPimport 'package:flutter/material.dart';
import 'package:map_launcher/map_launcher.dart';
import '/jh_common/utils/jh_map_utils.dart';
import '/jh_common/widgets/jh_text_list.dart';// ignore_for_file: avoid_printfinal List titleData = ['高德(JhMapUtils)','高德2(JhMapUtils)','百度(JhMapUtils)','腾讯(JhMapUtils)','三方库跳转高德(map_launcher)','三方库弹出地图列表(map_launcher)',
];class MapJumpTestPage extends StatefulWidget {const MapJumpTestPage({Key? key}) : super(key: key);State<MapJumpTestPage> createState() => _MapJumpTestPageState();
}class _MapJumpTestPageState extends State<MapJumpTestPage> {var latitude = 39.922869448132474;var longitude = 116.40748500823975;Widget build(BuildContext context) {return JhTextList(title: '跳转三方地图导航',dataArr: titleData,callBack: (index, str) {if (str == '高德(JhMapUtils)') {JhMapUtils.openAMapNavi(dLatitude: latitude, dLongitude: longitude);}if (str == '高德2(JhMapUtils)') {JhMapUtils.openAMapNavi2(latitude: latitude, longitude: longitude);}if (str == '百度(JhMapUtils)') {JhMapUtils.openBaiduMapNavi(dLatitude: latitude, dLongitude: longitude);}if (str == '腾讯(JhMapUtils)') {JhMapUtils.openTencentMapNavi(dLatitude: latitude, dLongitude: longitude);}if (str == '三方库跳转高德(map_launcher)') {_gotoMap();}if (str == '三方库弹出地图列表(map_launcher)') {_openMapsSheet(context);}},);}_gotoMap() async {// Get list of installed maps and launch firstfinal availableMaps = await MapLauncher.installedMaps;print(availableMaps); // [AvailableMap { mapName: Google Maps, mapType: google }, ...]// [// AvailableMap{// mapName: GoogleMaps,// mapType: google// },// AvailableMap{// mapName: Amap,// mapType: amap// },// AvailableMap{// mapName: BaiduMaps,// mapType: baidu// },// AvailableMap{// mapName: Tencent(QQMaps),// mapType: tencent// }// ]// await availableMaps.first.showMarker(// coords: Coords(latitude, longitude),// title: "Ocean Beach",// );// await availableMaps[1].showMarker(// coords: Coords(latitude, longitude),// title: "Ocean Beach",// );// Check if map is installed and launch it #var canIn = await MapLauncher.isMapAvailable(MapType.amap);print('canIn: $canIn');if (await MapLauncher.isMapAvailable(MapType.amap) == true) {await MapLauncher.showMarker(mapType: MapType.amap,coords: Coords(latitude, longitude),title: 'title',description: 'description',);}}_openMapsSheet(context) async {try {const title = "Ocean Beach";final availableMaps = await MapLauncher.installedMaps;showModalBottomSheet(context: context,builder: (BuildContext context) {return SafeArea(child: SingleChildScrollView(child: Wrap(children: <Widget>[for (var map in availableMaps)ListTile(onTap: () => map.showMarker(coords: Coords(latitude, longitude), title: title),title: Text(map.mapName),leading: const Icon(Icons.map, size: 30),),],),),);},);} catch (e) {print(e);}}
}
jh_map_utils实现代码
/// jh_map_utils.dart
///
/// Created by iotjin on 2023/05/06.
/// description:import 'dart:math';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'jh_device_utils.dart';class JhMapUtils {/// 跳转其他Appstatic Future<void> jumpApp({String? url, String message = '跳转失败!'}) async {final Uri uri = Uri.parse(url ?? '');if (await canLaunchUrl(uri)) {await launchUrl(uri);} else {debugPrint(message);// JhProgressHUD.showText(message);}}/// 判断地图是否有安装static Future<bool> isInstallMap(String url) async {// var url = Uri.parse(Uri.encodeFull(url));final Uri uri = Uri.parse(url);bool canLaunch = await canLaunchUrl(uri);debugPrint('canLaunch: $canLaunch');return canLaunchUrl(uri);}/// 跳转高德导航 - 路径规划/// 高德地图官方文档 - Android: https://lbs.amap.com/api/amap-mobile/guide/android/route/// 高德地图官方文档 - iOS: https://lbs.amap.com/api/amap-mobile/guide/ios/routestatic void openAMapNavi({double? sLatitude, // 起点纬度double? sLongitude, // 起点经度String sName = '', // 起点名称required double dLatitude, // 终点纬度required double dLongitude, // 终点经度String dName = '', // 终点名称String dev = '0', // 起终点是否偏移。0:lat和lon是已经加密后的,不需要国测加密;1:需要国测加密,可为空,但起点或终点不为空时,不能为空String t = '0', // t = 0 驾车; t = 1 公交; t = 2 步行; t = 3 骑行(骑行仅在V788以上版本支持)String message = '您没有安装高德地图,请先安装高德地图!',}) async {if (!JhDeviceUtils.isMobile) {return;}var type = JhDeviceUtils.isIOS ? 'iosamap://path?sourceApplication=applicationName&' : 'amapuri://route/plan/?';var url ='${type}sid=&slat=${sLatitude ?? ''}&slon=${sLongitude ?? ''}&sname=$sName&dlat=$dLatitude&dlon=$dLongitude&dname=$dName&dev=$dev&t=$t';// if (!(await canLaunchUrl(Uri.parse(url)))) {// debugPrint(message);// // JhProgressHUD.showText(message);// return;// }await launchUrl(Uri.parse(url));}/// 跳转高德导航/// 高德地图官方文档: https://lbs.amap.com/api/amap-mobile/guide/android/navigationstatic void openAMapNavi2({required double latitude,required double longitude,String poiName = '',String dev = '0', // 是否偏移(0:lat 和 lon 是已经加密后的,不需要国测加密; 1:需要国测加密)String message = '您没有安装高德地图,请先安装高德地图!',}) async {var device = JhDeviceUtils.isAndroid ? 'android' : 'ios';var url = '${device}amap://navi?sourceApplication=amap&poiname=$poiName&lat=$latitude&lon=$longitude&dev=$dev';// if (!(await canLaunchUrl(Uri.parse(url)))) {// debugPrint(message);// // JhProgressHUD.showText(message);// return;// }await launchUrl(Uri.parse(url));}/// 跳转百度导航 - 路径规划/// 百度地图官方文档: https://lbsyun.baidu.com/index.php?title=uri/api/androidstatic void openBaiduMapNavi({double? sLatitude, // 起点纬度double? sLongitude, // 起点经度String sName = '', // 起点名称required double dLatitude, // 终点纬度required double dLongitude, // 终点经度String dName = '', // 终点名称String mode = 'driving', // 导航模式,可选transit(公交)、driving(驾车)、walking(步行)和riding(骑行)默认:drivingString coordType ='gcj02', // 坐标类型,必选参数。coord_type= bd09ll 允许的值为:bd09ll(百度经纬度坐标) bd09mc(百度墨卡托坐标) gcj02(经国测局加密的坐标) wgs84(gps获取的原始坐标)String message = '您没有安装百度地图,请先安装百度地图!',}) async {var url ='baidumap://map/direction?origin=name:$sName|latlng:$sLatitude,$sLongitude&destination=name:$dName|latlng:$dLatitude,$dLongitude&mode=$mode&coord_type=$coordType';// if (!(await canLaunchUrl(Uri.parse(url)))) {// debugPrint(message);// // JhProgressHUD.showText(message);// return;// }await launchUrl(Uri.parse(url));}/// 跳转腾讯导航/// 腾讯地图官方文档: https://lbs.qq.com/webApi/uriV1/uriGuide/uriMobileRoutestatic void openTencentMapNavi({double? sLatitude, // 起点纬度double? sLongitude, // 起点经度String sName = '', // 起点名称required double dLatitude, // 终点纬度required double dLongitude, // 终点经度String dName = '', // 终点名称String type = 'drive', // 路线规划方式参数: 公交:bus 驾车:drive 步行:walk 骑行:bikeString referer = 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77', // 请填写开发者key,String message = '您没有安装腾讯地图,请先安装腾讯地图!',}) async {// 起点坐标,格式:lat,lng (纬度在前,经度在后,逗号分隔) 功能参数值:CurrentLocation :使用定位点作为起点坐标var formInfo = (sLatitude == null || sLongitude == null)? 'from=$sName&CurrentLocation': 'from=$sName&fromcoord=$sLatitude,$sLongitude';var url = 'qqmap://map/routeplan?type=$type&${formInfo}&to=$dName&tocoord=$dLatitude,$dLongitude&referer=$referer';// if (!(await canLaunchUrl(Uri.parse(url)))) {// debugPrint(message);// // JhProgressHUD.showText(message);// return;// }await launchUrl(Uri.parse(url));}static const double earthRadius = 6378.137; //地球半径//计算两点间距离static double distance(double lat1, double lng1, double lat2, double lng2) {double radLat1 = _rad(lat1);double radLat2 = _rad(lat2);double a = radLat1 - radLat2;double b = _rad(lng1) - _rad(lng2);double s = 2 * asin(sqrt(pow(sin(a / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2)));s *= earthRadius;s = (s * 10000).round() / 10000;return s;}static double _rad(double d) {return d * pi / 180.0; //角度转换成弧度}
}
相关文章:
Flutter - APP跳转高德、百度、腾讯、谷歌地图
demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新,请前往github查看最新代码 这里介绍的是不需要自己开发地图,直接通过给定的经纬度,跳转到三方地图APP调用导航的方式 一种是写的工具类,一种是通过调用三方…...
Flyway Desktop updated
Flyway Desktop updated 为比较工件序列化和反序列化添加了额外的调试日志记录。 Flyway Desktop现在将记住以前用于创建项目和匹配克隆的位置。 新的脱机许可工作流现在已在Microsoft Windows上启用。 现在,在配置目标数据库列表时,环境ID是可见的。 现…...
阿里云短信服务设置操作项目
在这里插入图片描述...
学习笔记|串口通信实战|简易串口控制器|sprintf函数|STC32G单片机视频开发教程(冲哥)|第二十一集(下):串口与PC通信
目录 3.串口通信实战实操简易的工作原理Tips:sprintf函数简介 总结课后练习 3.串口通信实战 做一个简易串口控制器。发送对应指令,让板子做相应的事情,或者传输数据(文本模式下发送,不要选择HEX)。 1.串口发送字符Ax\…...
卷积神经网络CNN学习笔记-卷积计算Conv2D函数的理解
目录 1.全连接层存在的问题2.卷积运算3.填充(padding)3.1填充(padding)的意义 4.步幅(stride)5.三维数据的卷积运算6.结合方块思考7.批处理8.Conv2D函数解析9.conv2d代码9.1 stride19.2 stride2 参考文章 1.全连接层存在的问题 在全连接层中,相邻层的神经元全部连接…...
收藏,安装报错信息汇总,MacOS上安装Adobe等软件/插件报错问题解决合集
打开允许“允许任何来源” 如何打开允许任何来源?在 Finder 菜单栏选择 【前往】 – 【实用工具 】,找到【终端】程序,双击打开,在终端窗口中输入:sudo spctl --master-disable 输入代码后,按【return 回车…...
Qt 报错:munmap_chunk(): invalid pointer解决方案
问题 在用Qt写程序的时候。报了munmap_chunk(): invalid pointer这个错误消息。 造成原因 在 Qt 程序中,这种错误可能出现在多种情况下,以下几点是容易造成此问题的原因: 函数未实现返回值:函数有返回值,但函数体中…...
【Java题】实现继承和多态的例子
一:题目 1.员工类Employee: (1)私有成员变量:姓名,年龄,工资 (2)提供无参,有参构造 (3)成员方法:work()方法——员工工作 …...
‘conda‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
原因:环境变量没有正确添加解决:我的电脑—右键属性—高级系统设置—环境变量—系统变量—Path—双击进入—新建,去安装Anaconda的目录下,找到Library中的bin,将此时的路径粘贴到此处...
C1N短网址 - 是如何做到行业领先的
今天从技术角度来聊下短网址的一些事情,市面上的短网址发展基本上经历了几个阶段。 短网址发展的几个阶段: 第一阶段:网址缩短,很纯粹的功能,各个大小公司都在做,门槛很低。典型代表:百度短网…...
【UE5】引入C++插件Plugins不在UE里出现
原因 未编译过C 原项目为蓝图项目,或者虽然为C项目,但并为编译过C. 解决 创建一个C脚本,让编辑器重启重新编译一遍。 如还不行,则打开Plugins插件面板,创建一个空的新的插件,再让引擎自动重启重新编译…...
第三部分:JavaScript
一:JavaScript介绍 JavaScript语言诞生主要是完成页面的数据验证。因此它运行在客户端,需要运行浏览器来解析执行JavaScript代码。 JavaScript是Net scape网景公司的产品,最早取名为LiveScript;为了吸引更多的程序员,更…...
Redis 命令—— 超详细操作演示!!!
内存数据库 Redis7 三、Redis 命令3.1 Redis 基本命令3.2 Key 操作命令3.3 String 型 Value 操作命令3.4 Hash 型 Value 操作命令3.5 List 型 Value 操作命令3.6 Set 型 Value 操作命令3.7 有序Set 型 Value 操作命令3.8 benchmark 测试工具3.9 简单动态字符串SDS3.10 集合的底…...
工业自动化控制通信协议Profinet系列-3、CoDeSys软PLC方案介绍
工业自动化控制通信协议Profinet系列-3、CoDeSys软PLC方案介绍 文章目录 工业自动化控制通信协议Profinet系列-3、CoDeSys软PLC方案介绍一、前言二、Profinet搭建资料收集三、CoDeSys系列四、接下来 一、前言 之前在树莓派desktop上已经成功编译运行测试程序,但是还…...
[补题记录] Atcoder Beginner Contest 293(E)
URL:https://atcoder.jp/contests/abc293 目录 E Problem/题意 Thought/思路 Code/代码 E Problem/题意 给出 A、X、M,求 。 Thought/思路 一开始想等比数列求和,但是 m 不保证是质数,所以不能用。 假设 dp[x] 表示&…...
R语言有关模型方面的函数(model.)介绍-model.matrix
R语言有关模型方面的函数(model.)介绍-model.matrix 引言model.matrix简单作用提取设计矩阵对有序因子与无序因子的处理(模型相关)手动编写contr.系列的函数写在最后引言 最近闲暇时间大量阅读了一些机器学习方面的R包源码,在此对阅读过程中的一些实用但是不常见的函数进行…...
owasp top 10
1、访问控制的崩溃: 通过身份验证的用户可以访问其他用户的信息,越权 达成方式:通过修改url、内部应用程序状态或html页面绕过 防范:除了公有资源外,默认情况下拒绝访问,严格判断权限,记录失败的…...
【FreeRTOS】【STM32】06 FreeRTOS的使用-动态创建多任务 FreeRTOS 的启动流程
主要流程参照【FreeRTOS】【STM32】06 FreeRTOS的使用-动态创建单任务 1.定义任务句柄 static TaskHandle_t AppTaskCreate_Handle NULL;2.硬件初始化 略 3.创建具体功能任务函数 见定义任务函数 4.使用xTaskCreate创建任务 xReturn xTaskCreate((TaskFunction_t )AppT…...
10月21日,每日信息差
今天是2023年10月21日,以下是为您准备的13条信息差 第一、东方物探公司与阿里云达成战略合作,逐步助力勘探行业实现智能化、自动化、绿色化和可持续化的目标 第二、九洲集团签约300MW集中式风电项目计划总投资21亿,项目达产后,预…...
C++学习笔记之三(函数指针、调用、动态内存、模板)
C 1、函数&指针1.1、指针函数1.2、函数指针1.2.1、函数指针作为函数的传入参数1.2.2、函数指针作为函数的返回值 2、传递2.1、值传递2.2、址传递2.3、引用传递 3、多态3.1、虚方法和抽象方法 4、动态内存5、模板5.1、函数模板5.2、类模板5.3、内联函数 1、函数&指针 1…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
