flutter获取地理定位:geolocator依赖详细用法

 本文使用geolocator插件实现app物理定位功能。

该插件的主要功能有:

  • 获取最后已知位置;
  • 获取设备当前位置;
  • 获取连续的位置更新;
  • 检查设备是否启用了定位服务;
  • 计算两个地理坐标之间的距离(米);
  • 计算两个地理坐标之间的方位;

如何安装:

 方法一:在pubspec.yaml文件中添加它,10.1.0是当前最新版本号,也可指定特定版本号。

然后在终端运行以下命令:

flutter packages get

方法二:直接在终端运行以下命令获取最新版本geolocator插件

flutter pub add geolocator

配置app环境 :

Android系统

1.在 "android\gradle.properties" 文件中添加以下内容:

android.useAndroidX=true
android.enableJetifier=true

2.确保将 "android/app/build.gradle "文件中的 compileSdkVersion 设置为 33(10.1.0版本时要求,不同版本可能要求不一样,具体看原依赖文档):

android {compileSdkVersion 33...
}

3.确保将所有 android. 依赖项替换为 AndroidX 对应项(完整列表可在此处找到:迁移到 AndroidX)。

4.打开 "android\app\src\main\AndroidManifest.xml" 文件,将以下两行中的一行添加为<manifest> 标签的直接子代(当这两种权限都配置时,geolocator将使用 ACCESS_FINE_LOCATION):

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

如果你目标用户用的是Android10或者以上的系统,就需要再添加ACCESS_BACKGROUND_LOCATION这条权限

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

IOS系统

打开 "ios\Runner\Info.plist" 文件,添加以下内容。string标签内为描述,可更改以贴合上下文。

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>

如果你想在应用程序处于后台时也能接收位置更新,你还需要在 XCode 项目中添加后台模式功能(项目 > 签名和功能 > "+ 功能 "按钮)并选择位置更新。(但要注意,在向 AppStore 提交应用程序时,你需要向苹果公司详细解释为什么您的应用程序需要这样做。如果苹果不满意您的解释,您的应用程序将被拒绝。)

使用 requestTemporaryFullAccuracy({purposeKey: "YourPurposeKey"}) 方法时,应在 Info.plist 文件中添加一个字典。第二个键(本例中称为 YourPurposeKey)应与 requestTemporaryFullAccuracy() 方法中传递的 purposeKey 相匹配

<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict><key>YourPurposeKey</key><string>The example App requires temporary access to the device&apos;s precise location.</string>
</dict>

简单使用举例:

权限配置完成后我们就可以开始使用地理定位依赖了,下面的代码举例说明了如何获取设备的当前位置,包括检查定位服务是否启用,以及检查/请求访问设备位置的权限:

/// 位置服务Future _determinePosition() async {bool serviceEnabled;LocationPermission permission;double longitude=0;double latitude=0;try {/// 手机GPS服务是否已启用。serviceEnabled = await Geolocator.isLocationServiceEnabled();if (!serviceEnabled) {//定位服务未启用,要求用户启用定位服务var res = await Geolocator.openLocationSettings();if (!res) {/// 被拒绝return;}}/// 是否允许app访问地理位置permission = await Geolocator.checkPermission();if (permission == LocationPermission.denied) {/// 之前访问设备位置的权限被拒绝,重新申请权限permission = await Geolocator.requestPermission();if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {/// 再次被拒绝。根据Android指南,你的应用现在应该显示一个解释性UI。return;}} else if (permission == LocationPermission.deniedForever) {/// 之前权限被永久拒绝,打开app权限设置页面await Geolocator.openAppSettings();return;}/// 允许访问地理位置,获取地理位置Position position = await Geolocator.getCurrentPosition();longitude = position.longitude;latitude = position.latitude;} catch (e) {print(e);}}

geolocator依赖的完整API:

 检查GPS是否启用:isLocationServiceEnabled

可用该方法检查手机GPS(全球定位系统)是否打开,以此进行不同操作

import 'package:geolocator/geolocator.dart';bool isLocationServiceEnabled  = await Geolocator.isLocationServiceEnabled();

然后可以调用 getServiceStatusStream监听服务状态变化。这将返回一个可以监听的 Stream<ServiceStatus>,以接收位置服务状态更新。

import 'package:geolocator/geolocator.dart';StreamSubscription<ServiceStatus> serviceStatusStream = Geolocator.getServiceStatusStream().listen((ServiceStatus status) {print(status);});

 检查是否允许APP获取位置权限:checkPermission

import 'package:geolocator/geolocator.dart';LocationPermission permission = await Geolocator.checkPermission();

 APP请求获取位置权限:requestPermission

import 'package:geolocator/geolocator.dart';LocationPermission permission = await Geolocator.requestPermission();

checkPermission 和 requestPermission 方法返回值说明

  • denied:用户拒绝了访问设备位置的权限。您可以再次申请权限(这也是初始权限状态)。
  • deniedForever:永久拒绝访问设备位置的权限。请求权限时,权限对话框将不会显示,直到用户在应用程序设置中更新权限。
  • whileInUse:仅当应用程序正在使用时才允许访问设备位置。
  • always:即使应用程序在后台运行,也允许访问设备位置。

打开相关设置页面:

在某些情况下,有必要询问用户并更新其设备设置。例如,用户最初永久拒绝了APP访问设备位置的权限,或者位置服务未启用(在 Android 上,自动解析不起作用)。在这种情况下,你可以使用 openAppSettingsopenLocationSettings 方法立即将用户重定向到设备的设置页面。 

安卓系统中,openAppSettings 方法将把用户重定向到应用程序特定设置,用户可以在此重新设置APP相关权限。

openLocationSettings 方法将弹窗询问或把用户重定向到设备位置设置,用户可在此启用/禁用位置服务。


iOS 系统中,我们不允许打开特定的设置页面,因此这两种方法都会将用户重定向到 "设置应用",用户可以从该应用导航到正确的设置类别,以更新权限或启用/禁用位置服务。

import 'package:geolocator/geolocator.dart';await Geolocator.openAppSettings();
await Geolocator.openLocationSettings();

获取当前位置:getCurrentPosition

  • desiredAccuracy:app希望接收的位置数据的精度(可选值在文章结尾有说明);
  • timeLimit:获取当前位置所允许的最长时间。超过时间限制后,将抛出 TimeOutException 异常,并取消调用。默认情况下未配置任何限制,即永不超时。
import 'package:geolocator/geolocator.dart';Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

获取最后已知位置:getLastKnownPosition

import 'package:geolocator/geolocator.dart';Position? position = await Geolocator.getLastKnownPosition();

监听持续性的位置变化:getPositionStream

  • accuracy:应用程序希望接收的位置数据的精确度;
  • distanceFilter:在生成更新事件之前,设备水平移动的最小距离(以米为单位);
  • timeLimit:位置更新之间允许的最长间隔时间。超过时限后,将抛出 TimeOutException 异常,并取消数据流。默认情况下未配置任何限制,即永不超时。
import 'package:geolocator/geolocator.dart';final LocationSettings locationSettings = LocationSettings(accuracy: LocationAccuracy.high,distanceFilter: 100,
);
StreamSubscription<Position> positionStream = Geolocator.getPositionStream(locationSettings: locationSettings).listen((Position? position) {print(position == null ? 'Unknown' : '${position.latitude.toString()}, ${position.longitude.toString()}');});

在某些情况下,有必要指定一些平台特定的设置。这可以通过使用特定平台的 AndroidSettings 或 AppleSettings 类来实现。使用特定平台类时,还必须导入特定平台包。示例:

import 'package:geolocator/geolocator.dart';
import 'package:geolocator_apple/geolocator_apple.dart';
import 'package:geolocator_android/geolocator_android.dart';late LocationSettings locationSettings;if (defaultTargetPlatform == TargetPlatform.android) {locationSettings = AndroidSettings(accuracy: LocationAccuracy.high,distanceFilter: 100,forceLocationManager: true,intervalDuration: const Duration(seconds: 10),//(可选)设置前台通知配置,使应用程序在进入后台时保持活跃foregroundNotificationConfig: const ForegroundNotificationConfig(notificationText:"Example app will continue to receive your location even when you aren't using it",notificationTitle: "Running in Background",enableWakeLock: true,));
} else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {locationSettings = AppleSettings(accuracy: LocationAccuracy.high,activityType: ActivityType.fitness,distanceFilter: 100,pauseLocationUpdatesAutomatically: true,// 只有当我们的APP在后台启动时才设置为trueshowBackgroundLocationIndicator: false,);
} else {locationSettings = LocationSettings(accuracy: LocationAccuracy.high,distanceFilter: 100,);
}StreamSubscription<Position> positionStream = Geolocator.getPositionStream(locationSettings: locationSettings).listen((Position? position) {print(position == null ? 'Unknown' : '${position.latitude.toString()}, ${position.longitude.toString()}');});

 计算两个坐标间的距离:distanceBetween

  • startLatitude:起始位置的经度。
  • startLongitude:起始位置的纬度。
  • endLatitude:终点位置的经度。
  • endLongitude:终点位置的维度。
import 'package:geolocator/geolocator.dart';double distanceInMeters = Geolocator.distanceBetween(52.2165157, 6.9437819, 52.3546274, 4.8285838);

 计算两个坐标间的方位:bearingBetween

同样需要上述四个参数。

import 'package:geolocator/geolocator.dart';double bearing = Geolocator.bearingBetween(52.2165157, 6.9437819, 52.3546274, 4.8285838);

定位精度枚举值

Android

  • lowest:确保不会使用额外的功率来计算位置。这意味着该请求将充当被动监听器,只接收代表其他客户端计算的 "空闲 "位置,而不会只代表该请求计算位置。(可能不会返回任何位置信息)
  • low:以可能牺牲定位精度为代价,对低功耗进行权衡。
  • medium:要求在定位精度和耗电量之间进行权衡。
  • high:要求权衡高精度定位和可能的额外耗电量。

IOS  请求的数据越详细,对电池消耗的影响就越大。

  • lowest:精确到最近的三公里。
  • low:精确到最近的一公里。
  • medium:精度精确到一百米以内。
  • high:精确到距离所需目标十米以内。
  • best:可用的最佳精度级别。
  • bestForNavigation:使用附加传感器数据以方便导航应用程序的最高精度。

好了,去玩吧 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/635465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI时代—ChatGPT-4.5的正确打开方式

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言4.5key价格泄漏ChatGPT4.0使用地址ChatGPT正确打开方式最新功能语音助手存档…

微信小程序(七)navigator点击效果

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.默认效果 2.无效果 3.激活效果 源码&#xff1a; index.wxml //如果 <navigator url"/pages/logs/logs">跳转到log页面&#xff08;默认&#xff09; </navigator><navigator url&q…

从零开始,自己搭建一个autonomous mobile robot做gazebo仿真(1):mobile robot建模与添加差速控制器

这样一个简单的mobile robot模型 首先写xacro文件&#xff0c;创建 link joint transmission <?xml version"1.0"?> <robot xmlns:xacro"http://www.ros.org/wiki/xacro" name"whill_modelc" ><xacro:property name"PI&q…

【点云、图像】学习中 常见的数学知识及其中的关系与python实操[更新中]

文章目录 前言一、平均值、方差、协方差平均值&#xff08;mean&#xff09;np.mean()方差&#xff08;variance&#xff09;np.var()总体方差 np.var(a, ddof0)无偏样本方差np.var(a, ddof1)有偏样本方差标准差&#xff08;standard deviation&#xff09;np.std(a, ddof1)默认…

Docker 部署考核

Docker安装 安装必要的系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 添加docker-ce安装源&#xff1a; yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 配置阿里云Docker Yum源: yum-config-manager --ad…

2024.1.19 网络编程 作业

思维导图 练习题 1> UDP传输实现聊天室 服务器端 #include <myhead.h> #define SER_IP "192.168.125.151" #define SER_PORT 9999 typedef struct Msg {char user[32]; //用户名int type; //执行操作1.登录、2.发消息、0.退出char text[1024]; …

【Flink-CDC】Flink CDC 介绍和原理概述

【Flink-CDC】Flink CDC 介绍和原理概述 1&#xff09;基于查询的 CDC 和基于日志的 CDC2&#xff09;Flink CDC3&#xff09;Flink CDC原理简述4&#xff09;基于 Flink SQL CDC 的数据同步方案实践4.1.案例 1 : Flink SQL CDC JDBC Connector4.2.案例 2 : CDC Streaming ETL…

在 Python 中检查一个数字是否是同构数

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 同构数&#xff0c;又称为自守数或自同构数&#xff0c;是一类特殊的数字&#xff0c;它们具有一种有趣的性质&#xff1a;将其平方后的数字&#xff0c;可以通过某种方式重新排列得到原来的数字。本文将详细介绍…

2024Java高频面试题之MQ消息中间件,面试都问些什么?(附详细答案)

最近很多同学问我有没有java学习资料&#xff0c;我根据我从小白到架构师多年的学习经验整理出来了一份50W字面试解析文档、简历模板、学习路线图、java必看学习书籍 、 需要的小伙伴 可以关注我公众号&#xff1a;“ Tom聊架构 ”&#xff0c; 回复暗号&#xff1a;“ 578”即…

Dockerfile镜像构建

Dockerfile镜像构建 1、部署harbor仓库 #部署docker #解压harbor安装包 rootharbor:~# cd /app/harbor/ rootharbor:/app/harbor# ll total 597560 drwxr-xr-x 3 root root 180 Jan 13 13:17 ./ drwxr-xr-x 4 root root 77 Jan 13 13:14 ../ drwxr-xr-x 3 root …

element-ui 打包流程源码解析(下)

目录 目录结构和使用1&#xff0c;npm 安装1.1&#xff0c;完整引入1.2&#xff0c;按需引入 2&#xff0c;CDN3&#xff0c;国际化 接上文&#xff1a;element-ui 打包流程源码解析&#xff08;上&#xff09; 文章中提到的【上文】都指它 ↑ 目录结构和使用 我们从使用方式来…

零基础学Python(3)— 注释、代码缩进和编码规范

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。在使用Python语言进行编程的时候&#xff0c;需要遵循一定的规范标准。本节课就带大家了解下Python语言在注释、缩进和编码方面的规范!~&#x1f308; 目录 &#x1f680;1.注释 &#x1f680;2.代码缩进 &#x1f68…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--大模型、扩散模型、视觉导航

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 VX关注&#xff0c;并留下邮箱可获得每日定时推送 分类: 大语言模型LLM视觉模型VLM扩散模型视觉导航具身智能&#xff0c;机器人强化…

深入Android S (12.0) 探索Framework之输入子系统InputReader的流程

Framework层之输入系统 第一篇 深入Android S (12.0) 探索Framework之输入系统IMS的构成与启动 第二篇 深入Android S (12.0) 探索Framework之输入子系统InputReader的流程 文章目录 Framework层之输入系统前言一、基础知识1、输入子系统2、INotify 与 Epoll2.1、INotify 机制…

SpringBoot+dynamic-datasource实现多数据源(msyql、sqlserver、postgresql)手动切换

场景 SpringBootMybatisPlusdynamic-datasources实现连接Postgresql和mysql多数据源&#xff1a; SpringBootMybatisPlusdynamic-datasources实现连接Postgresql和mysql多数据源-CSDN博客 上面实现通过注解和配置文件的方式去进行多数据源操作。 如果业务需求&#xff0c;比…

Spark流式读取文件数据

流式读取文件数据 from pyspark.sql import SparkSession ss SparkSession.builder.getOrCreate() # todo 注意1&#xff1a;流式读取目录下的文件 --》一定一定要是目录&#xff0c;不是具体的文件&#xff0c;# 目录下产生新文件会进行读取# todo 注意点2&#xff1…

大模型日报-20240120

这里写目录标题 视觉Mamba来了&#xff1a;速度提升2.8倍&#xff0c;内存能省87%一键实景转动画&#xff0c;清华系初创公司全球首发4D骨骼动画框架&#xff0c;还能生成个性化角色如何利用革命性的蛋白质结构工具来发现药物&#xff1f;AlphaFold 发现了数千种可能的致幻剂扎…

Unity关于纹理图片格式带来的内存问题和对预制体批量格式和大小减半处理

我们经常会遇到内存问题&#xff0c;这次就是遇到很多图片的默认格式被改成了RGB32&#xff0c;导致Android打包后运行内存明显增加。 发生了什么 打包Android后&#xff0c;发现经常崩溃&#xff0c;明显内存可能除了问题&#xff0c;看了内存后发现了问题。 见下图&#xf…

1.C语言——基础知识

C语言基础知识 1.第一个C语言程序2.注释3.标识符4.关键字5.数据类型6.变量7.常量8.运算符9.输入输出输入输出 1.第一个C语言程序 C语言的编程框架 #include <stdio.h> int main() {/* 我的第一个 C 程序 */printf("Hello, World! \n");return 0; }2.注释 单行…

【Qt5】QString的成员函数chop

2024年1月19日&#xff0c;周五下午 QString 的 chop 方法用于从字符串的末尾移除指定数量的字符。这个方法会修改原始字符串&#xff0c;并返回 void。 下面是一个简单的示例&#xff1a; #include <QString> #include <QDebug>int main() {QString originalStr…