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); } }

相关新闻

最新新闻

【Linux】二十四.线程篇一《一文吃透Linux线程全面解析:概念、内存管理、优缺点与用途》

【Linux】二十四.线程篇一《一文吃透Linux线程全面解析:概念、内存管理、优缺点与用途》

线程的概念线程是进程内的一个执行分支,是在进程内部运行的一个执行流,是CPU调度的基本单位。通过一下角度我们来彻底对线程的概念进行清晰的解读:1-1什么是线程感性理解线程先搞清楚两个基本概念:进程 内核数据结构(…

2026/7/24 21:48:26
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?

宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?

这里写自定义目录标题前言一、为什么要给Redis设置密码?二、方法一:通过宝塔面板图形界面修改三、方法二:通过SSH修改配置文件前言 最近在加固服务器安全时,需要给宝塔面板里的Redis设置一个强密码。 本以为在宝塔面板的Redis图形…

2026/7/24 21:48:26
GPT-Image-2风格词表:写实风格关键词大全,精准提升AI写实出图质感与真实度

GPT-Image-2风格词表:写实风格关键词大全,精准提升AI写实出图质感与真实度

目录 前言一、AI工具聚合赋能:高效打磨写实风格专属提示词二、GPT-Image-2写实风格出图的核心判定逻辑三、GPT-Image-2通用写实基础关键词(全局通用) 核心基础词画质精度词使用技巧 四、细分场景写实专属关键词表(精准适配&#…

2026/7/24 21:48:26
AI NPC从“脚本傀儡”到“可信角色”的跃迁路径(2024 GDC获奖项目底层逻辑首次公开)

AI NPC从“脚本傀儡”到“可信角色”的跃迁路径(2024 GDC获奖项目底层逻辑首次公开)

更多请点击: https://intelliparadigm.com 第一章:AI NPC从“脚本傀儡”到“可信角色”的跃迁路径(2024 GDC获奖项目底层逻辑首次公开) 传统NPC长期受限于状态机与对话树的硬编码范式,行为可预测、反应同质化、情感无…

2026/7/24 21:48:25
别再瞎试了!用“ICE-R”五步法重构提示词——20年AI系统架构师首次公开私藏方法论(仅剩最后217个免费下载名额)

别再瞎试了!用“ICE-R”五步法重构提示词——20年AI系统架构师首次公开私藏方法论(仅剩最后217个免费下载名额)

更多请点击: https://intelliparadigm.com 第一章:AI 提示词工程入门 提示词工程(Prompt Engineering)是人与大语言模型高效协作的核心技能,它并非编程语言,而是一种结构化表达意图、约束输出边界、引导模…

2026/7/24 21:48:25
佳能喷墨机打印机提示1700,1701,1702,5B00,5B02 5B04,P07,E08这些报错只需清零即可,常见型号ts3380,mg3660,g3800,g4810,ts9120亲测完美。

佳能喷墨机打印机提示1700,1701,1702,5B00,5B02 5B04,P07,E08这些报错只需清零即可,常见型号ts3380,mg3660,g3800,g4810,ts9120亲测完美。

蓝奏云:点这里下载 密码:00 百度云:点这里下载 备用:pan.baidu.com/s/1gls2G4rqWWP-Mw-z6tVjnQ?pwd0000 常见型号如下: G1000、G1100、G1200、G1400、G1500、G1800、G1900、G1010、G1110、G1120、G1410、G1420、G1411、G151…

2026/7/24 21:43:25

月新闻