尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Flutter---GPS定位(2)
功能跳转主流地图APP实现步骤1.引入外部库map_launcher: ^4.5.0 #检测手机是否安装了主流地图 APP2.增加导航弹窗void showBottomSheetDialog(BuildContext context){ showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)) ), builder: (BuildContext context){ return Container( padding: EdgeInsets.symmetric( vertical: 20, //horizontal: 10 ), height: 250, child: Column( children: [ GestureDetector( onTap: () async { goGaodeMap(); }, child: Container( width: 325, height: 52, decoration: BoxDecoration( color: Color(0xFF4AC6AD).withOpacity(0.8), borderRadius: BorderRadius.circular(10) ), child: Center( child: Text(高德地图,style: TextStyle(color:Colors.white,fontSize: 18),), ), ), ), SizedBox(height: 5,), GestureDetector( onTap: (){ //跳转百度地图 goBaiduMap(); }, child: Container( width: 325, height: 52, decoration: BoxDecoration( color: Color(0xFF4AC6AD).withOpacity(0.8), borderRadius: BorderRadius.circular(10) ), child: Center( child: Text(百度地图,style: TextStyle(color:Colors.white,fontSize: 18),), ), ), ), SizedBox(height: 25,), Container( height: 1, width: double.infinity, color: Color(0xFFA8A8A8), ), SizedBox(height: 15,), GestureDetector( onTap: (){ Navigator.pop(context); }, child: Container( width: 325, height: 52, decoration: BoxDecoration( color: Color(0xFFA8A8A8), borderRadius: BorderRadius.circular(10) ), child: Center( child: Text(取消,style: TextStyle(color:Colors.white,fontSize: 18),), ), ), ), ], ), ); } ); }3.跳转地图的具体方法///跳转高德地图 Futurevoid goGaodeMap() async{ try { if (_currentPosition null) { Fluttertoast.showToast(msg: 请先获取当前位置); return; } // 检查高德地图是否安装 bool isAmapAvailable await map_launcher.MapLauncher.isMapAvailable(map_launcher.MapType.amap); if (isAmapAvailable) { print(高德地图已安装准备跳转); if (_currentAddress ! null) { await map_launcher.MapLauncher.showMarker( mapType: map_launcher.MapType.amap, coords: map_launcher.Coords( _currentPosition!.latitude, _currentPosition!.longitude ), title: , // 使用设备名称 description: 耳机位置, // 可选描述 ); print(跳转成功); } else { print(无法获取耳机位置); Fluttertoast.showToast(msg: 无法获取耳机位置); } } else { print(高德地图未安装); Fluttertoast.showToast(msg: 请先安装高德地图); } } catch (e) { print(跳转失败: $e); Fluttertoast.showToast(msg: 跳转失败); } Navigator.pop(context); } ///跳转百度地图 Futurevoid goBaiduMap() async{ try { if (_currentPosition null) { Fluttertoast.showToast(msg: 请先获取当前位置); return; } // 检查百度地图是否安装 bool isBaiduAvailable await map_launcher.MapLauncher.isMapAvailable(map_launcher.MapType.baidu); if (isBaiduAvailable) { print(高德地图已安装准备跳转); //耳机的位置 if (_currentAddress ! null) { await map_launcher.MapLauncher.showMarker( mapType: map_launcher.MapType.baidu, coords: map_launcher.Coords( _currentPosition!.latitude, _currentPosition!.longitude ), title: , // 使用设备名称 description: 耳机位置, // 可选描述 ); print(跳转成功); } else { print(无法获取耳机位置); Fluttertoast.showToast(msg: 无法获取耳机位置); } } else { print(高德地图未安装); Fluttertoast.showToast(msg: 请先安装百度地图); } } catch (e) { print(跳转失败: $e); Fluttertoast.showToast(msg: 跳转失败); } Navigator.pop(context); }代码实例import package:flutter/cupertino.dart; import package:flutter/material.dart; import package:fluttertoast/fluttertoast.dart; import package:geocoding/geocoding.dart; import package:geolocator/geolocator.dart; import package:map_launcher/map_launcher.dart as map_launcher; import location_service.dart; /// 设备查找页面 class DeviceFindPage extends StatefulWidget { const DeviceFindPage({super.key}); override StateStatefulWidget createState() _DeviceFindPageState(); } class _DeviceFindPageState extends StateDeviceFindPage { // 定位相关 final LocationService _locationService LocationService(); //定位服务实例 Position? _currentPosition; //当前位置 String _currentAddress ; //当前地址 bool _isLoadingLocation false; //加载状态 bool _hasLocationPermission false; //权限状态 // 文本资源 String findDevice 查找设备; String tapRing 点击唤醒; String tapRingTips 温馨提示唤醒设备后会发出声音请注意聆听; String addressTips 温馨提示app会标记设备断联前的最后位置您可以打开点击右边图标转进导航软件查看位置; override void initState() { super.initState(); // 设置定位回调 _setupLocationCallbacks(); // 页面加载时自动获取位置 WidgetsBinding.instance.addPostFrameCallback((_) { _getLocationAndAddress(); }); } override void dispose() { // 释放定位资源 _locationService.dispose(); super.dispose(); } //设置定位回调 void _setupLocationCallbacks() { _locationService.onLocationUpdated (Position position) { if (mounted) { setState(() { _currentPosition position; _hasLocationPermission true; }); // 位置更新时重新获取地址 _getAddressFromLatLng(position.latitude, position.longitude); } }; _locationService.onError (String error) { // Log.d(定位错误: $error); if (mounted) { setState(() { _currentAddress 定位失败: $error; _isLoadingLocation false; }); // 显示提示 ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(定位错误: $error), backgroundColor: Colors.red, ), ); } }; } //获取位置和地址 Futurevoid _getLocationAndAddress() async { if (_isLoadingLocation) return; setState(() { _isLoadingLocation true; _currentAddress 正在获取位置...; }); try { // 获取单次定位 Position? position await _locationService.getCurrentLocation(); if (position ! null mounted) { setState(() { _currentPosition position; _hasLocationPermission true; }); // 获取地址 await _getAddressFromLatLng(position.latitude, position.longitude); } } catch (e) { // Log.d(❌ 获取定位失败: $e); if (mounted) { setState(() { _currentAddress 获取位置失败请检查GPS设置; }); } } finally { if (mounted) { setState(() { _isLoadingLocation false; }); } } } //经纬度转地址 Futurevoid _getAddressFromLatLng(double latitude, double longitude) async { try { //地址解析 ListPlacemark placemarks await placemarkFromCoordinates( latitude, longitude, localeIdentifier: zh_CN, // 中文显示 ); if (placemarks.isNotEmpty mounted) { Placemark place placemarks[0]; // 构建详细地址 ListString addressParts []; // //国家 // if (place.country ! null place.country!.isNotEmpty) { // addressParts.add(place.country!); // } //省份 // if (place.administrativeArea ! null place.administrativeArea!.isNotEmpty) { // Log.d(⭐administrativeArea当前得到的值为${place.administrativeArea!}); // addressParts.add(place.administrativeArea!); // } // //城市 // if (place.locality ! null place.locality!.isNotEmpty) { // Log.d(⭐locality当前得到的值为${place.locality!}); // addressParts.add(place.locality!); // } // //区县 // if (place.subLocality ! null place.subLocality!.isNotEmpty) { // Log.d(⭐subLocality当前得到的值为${place.subLocality!}); // addressParts.add(place.subLocality!); // } //街道 if (place.street ! null place.street!.isNotEmpty) { // Log.d(⭐street当前得到的值为${place.street!}); addressParts.add(place.street!); } String fullAddress addressParts.join( ); // 如果地址为空使用经纬度 if (fullAddress.isEmpty) { fullAddress 纬度: $latitude, 经度: $longitude; } setState(() { _currentAddress fullAddress; _isLoadingLocation false; }); // Log.d( 当前地址: $fullAddress); // 如果需要上传到服务器在这里调用 // await YourHttpService.uploadLocation(latitude, longitude, fullAddress); } } catch (e) { // Log.d(❌ 获取地址失败: $e); if (mounted) { setState(() { _currentAddress 获取地址失败 (经纬度: $latitude, $longitude); _isLoadingLocation false; }); } } } override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xFFF5FCFF), appBar: AppBar( backgroundColor: Color(0xFFF5FCFF), leading: IconButton( onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back_ios), ), title: Text( findDevice, style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), ), centerTitle: true, ), body: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFFF5FCFF), Color(0xFFF2F4F5), ], ), ), child: Column( children: [ SizedBox(height: 10), // 查找容器 _buildFindContainer(), SizedBox(height: 40), // 详细地址显示定位信息 _buildAddress(), ], ), ), ); } // 查找容器 Widget _buildFindContainer() { return Container( width: double.infinity, height: 352, margin: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(40), gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFFCFFFF5), Color(0xFFFFFFFF), ], ), boxShadow: [ BoxShadow( color: Color(0xFF000000).withOpacity(0.1), offset: Offset(3, 0), spreadRadius: 3, blurRadius: 5, ), ], ), child: Column( children: [ SizedBox(height: 20), // 产品图 Container( width: 150, height: 150, decoration: BoxDecoration( shape: BoxShape.circle, color: Color(0xFF777777).withOpacity(0.3), border: Border.all( color: Color(0xFF777777).withOpacity(0.2), width: 20, ), ), child: Center( child: Text(产品图), ), ), SizedBox(height: 50), // 响铃按钮 GestureDetector( onTap: () { // 点击时触发响铃 // Log.d(点击唤醒设备); }, child: Container( height: 52, width: 129, decoration: BoxDecoration( borderRadius: BorderRadius.circular(26), color: Color(0xFF4AC6AD), boxShadow: [ BoxShadow( color: Color(0xFF000000).withOpacity(0.1), offset: Offset(3, 0), spreadRadius: 3, blurRadius: 5, ), ], ), child: Center( child: Text( tapRing, style: TextStyle(color: Colors.white, fontSize: 18), ), ), ), ), Spacer(), // 温馨提示 Text( *$tapRingTips*, style: TextStyle(color: Color(0xFF3D3D3D), fontSize: 12), ), SizedBox(height: 20), ], ), ); } // 详细地址 Widget _buildAddress() { return Container( width: double.infinity, height: 196, margin: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(31), color: Colors.white, boxShadow: [ BoxShadow( color: Color(0xFF000000).withOpacity(0.1), offset: Offset(3, 0), spreadRadius: 3, blurRadius: 5, ), ], ), child: Padding( padding: EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ //地址行 Row( children: [ //地址 Expanded(child: Text(_currentAddress,style: TextStyle(fontSize: 15,color: Color(0xFF3D3D3D)),)), //定位按钮 IconButton( onPressed: (){ showBottomSheetDialog(context); }, icon: Icon(Icons.navigation), ) ], ), //分割线 Container( height: 1, width: double.infinity, color: Colors.black.withOpacity(0.1), ), Spacer(), //温馨提示 Text( *$addressTips*, style: TextStyle(color: Color(0xFF3D3D3D), fontSize: 12), ), SizedBox(height: 5,), ], ), ), ); } //导航弹窗 void showBottomSheetDialog(BuildContext context){ showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)) ), builder: (BuildContext context){ return Container( padding: EdgeInsets.symmetric( vertical: 20, //horizontal: 10 ), height: 250, child: Column( children: [ GestureDetector( onTap: () async { goGaodeMap(); }, child: Container( width: 325, height: 52, decoration: BoxDecoration( color: Color(0xFF4AC6AD).withOpacity(0.8), borderRadius: BorderRadius.circular(10) ), child: Center( child: Text(高德地图,style: TextStyle(color:Colors.white,fontSize: 18),), ), ), ), SizedBox(height: 5,), GestureDetector( onTap: (){ //跳转百度地图 goBaiduMap(); }, child: Container( width: 325, height: 52, decoration: BoxDecoration( color: Color(0xFF4AC6AD).withOpacity(0.8), borderRadius: BorderRadius.circular(10) ), child: Center( child: Text(百度地图,style: TextStyle(color:Colors.white,fontSize: 18),), ), ), ), SizedBox(height: 25,), Container( height: 1, width: double.infinity, color: Color(0xFFA8A8A8), ), SizedBox(height: 15,), GestureDetector( onTap: (){ Navigator.pop(context); }, child: Container( width: 325, height: 52, decoration: BoxDecoration( color: Color(0xFFA8A8A8), borderRadius: BorderRadius.circular(10) ), child: Center( child: Text(取消,style: TextStyle(color:Colors.white,fontSize: 18),), ), ), ), ], ), ); } ); } ///跳转高德地图 Futurevoid goGaodeMap() async{ try { if (_currentPosition null) { Fluttertoast.showToast(msg: 请先获取当前位置); return; } // 检查高德地图是否安装 bool isAmapAvailable await map_launcher.MapLauncher.isMapAvailable(map_launcher.MapType.amap); if (isAmapAvailable) { print(高德地图已安装准备跳转); if (_currentAddress ! null) { await map_launcher.MapLauncher.showMarker( mapType: map_launcher.MapType.amap, coords: map_launcher.Coords( _currentPosition!.latitude, _currentPosition!.longitude ), title: , // 使用设备名称 description: 耳机位置, // 可选描述 ); print(跳转成功); } else { print(无法获取耳机位置); Fluttertoast.showToast(msg: 无法获取耳机位置); } } else { print(高德地图未安装); Fluttertoast.showToast(msg: 请先安装高德地图); } } catch (e) { print(跳转失败: $e); Fluttertoast.showToast(msg: 跳转失败); } Navigator.pop(context); } ///跳转百度地图 Futurevoid goBaiduMap() async{ try { if (_currentPosition null) { Fluttertoast.showToast(msg: 请先获取当前位置); return; } // 检查百度地图是否安装 bool isBaiduAvailable await map_launcher.MapLauncher.isMapAvailable(map_launcher.MapType.baidu); if (isBaiduAvailable) { print(高德地图已安装准备跳转); //耳机的位置 if (_currentAddress ! null) { await map_launcher.MapLauncher.showMarker( mapType: map_launcher.MapType.baidu, coords: map_launcher.Coords( _currentPosition!.latitude, _currentPosition!.longitude ), title: , // 使用设备名称 description: 耳机位置, // 可选描述 ); print(跳转成功); } else { print(无法获取耳机位置); Fluttertoast.showToast(msg: 无法获取耳机位置); } } else { print(高德地图未安装); Fluttertoast.showToast(msg: 请先安装百度地图); } } catch (e) { print(跳转失败: $e); Fluttertoast.showToast(msg: 跳转失败); } Navigator.pop(context); } }
RELATED

相关推荐

没有开放集成与低代码,协同中台只是空谈

没有开放集成与低代码,协同中台只是空谈

当 CIO 查看企业 IM 后台时,常会发现一个尴尬的事实:每天超过 90% 的业务消息都在讨论订单、审批、客户变更,但这些对话永远停留在聊天窗口里,无法直接驱动 ERP 审批流,也不能自动同步到 CRM 客户时间线。另一边&#…

📅 2026/11/5 9:38:06
一些感受与总结

一些感受与总结

prd对齐,那些情况要考虑,那些要做哪些不做trd评审,刚好为ai coding材料对齐,遇到问题多问,多和产品、研发和测试同学联系(终于知道以前为什么“明明是”这样却要拉一个会,明确哪些做哪些不做设计…

📅 2026/11/12 1:08:47
YOLOv10目标检测:环境配置与WebUI训练指南

YOLOv10目标检测:环境配置与WebUI训练指南

1. YOLOv10 项目概述YOLOv10 作为 Ultralytics 最新发布的实时目标检测模型,在 2024 年 5 月由清华大学团队推出后立即引发计算机视觉领域的广泛关注。这个号称"下一代视觉 AI"的模型系列最引人注目的突破在于完全摒弃了传统目标检测中必不可少的 NMS&…

📅 2026/11/7 19:36:41
MORE NEWS

更多资讯

📰

南昌电工证复审如何复报名入口与办理流程值不值得考

南昌电工证复审如何复报名入口与办理流程值不值得考 学历不高怕报不上名?南昌电工证复审如何复?这是很多一线电工最关心的问题。尤其对于那些没有高学历背景,但多年从事电工工作的朋友们来说,复审门槛和报名流程往往成了心里的“坎儿”。今天咱们不绕弯子…

📰

高压电工证招考题库保姆级教程:避开报名陷阱,一次拿证

高压电工证招考题库保姆级教程:避开报名陷阱,一次拿证 你是不是也在担心不知道去哪报名怕被中介坑?别急,这期内容专门为你准备, 高压电工证招考题库保姆级教程 ,手把手教你从报名到拿证的每一步,不再被各种培训机构套路。…

📰

哪里可以查询到电工证报名费多少钱

电工证哪里可以查询到 上岗必备的证件怎么考 你是不是正在找电工证,急需上岗找工作?别急,这篇文章专门为你准备,讲清楚电工证怎么查、怎么考、怎么用,还能帮你避坑省钱。…

📰

哪里可以查询到电工证报名入口与办理流程

电工证哪里可以查询到?实操考试心里没底怕挂科,先看这些细节 实操考试心里没底怕挂科?你不是一个人。每年都有不少电工证考试不过的人,不是因为技术差,而是因为不知道怎么准备、哪里能查到最新信息,甚至连报名流程都摸不着头绪。尤其是像你这样在周口干…

📰

汉中考电工证在哪 别踩坑!学历不高也能拿下电工证

汉中考电工证在哪 别踩坑!学历不高也能拿下电工证 学历不高怕报不上名?汉中考电工证在哪考?很多人一听到“电工证”就想到要学历、要文凭、要各种证明,但其实不然, 汉中考电工证在哪…

📰

三江电工证报考条件保姆级教程:怕考不过白交培训费?看这篇就够了

三江电工证报考条件保姆级教程:怕考不过白交培训费?看这篇就够了 你是不是也在担心,花了钱报名三江电工证,最后却因为条件不符合或者考不过,白交了培训费?别急,这篇文章从郑州应届工程类毕业生的视角出发,详细给你讲清楚三江电工证的报考条件,帮你避…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬