使用Flutter定位包获取地理位置

目录
  • Flutter 中获取地理位置
    • 先决条件
    • 使用 Flutter 定位包
      • 设置
      • 位置权限
      • 获取当前位置
    • 使用 Flutter 地理编码包
      • 设置
      • 获取地址
    • 常见的陷阱
    • 结论

Flutter 中获取地理位置

如今,发现用户位置是移动应用程序非常常见且功能强大的用例。如果您曾经尝试过在 Android 中实现位置,您就会知道样例代码会变得多么复杂和混乱。

但这与 Flutter 不同——它有很多令人惊叹的包,可以为您抽象出样板代码,并使实现地理定位成为梦想。另一个好的方面是您可以在 Android 和 iOS 上获得这些功能。

让我们快速浏览一下我们今天正在构建的用于收集位置数据的内容:

本文将带您了解两个最流行且易于使用的 Flutter 地理定位包。

让我们从location开始,这是Flutter 最喜欢的包。这很简单。只需三个简单的步骤,您就可以获取当前用户位置以及处理位置权限。

先决条件

在继续前进之前,让我们快速检查一下我们需要的东西:

  • FlutterSDK
  • 编辑器:您可以使用 Visual Code 或 Android Studio
  • 至少对 Flutter 有初级的了解

差不多就是这样!

使用 Flutter 定位包

设置

将依赖项添加到您的文件中:pubspec.yaml

    location: ^4.3.0

由于 Android 和 iOS 处理权限的方式不同,因此我们必须在每个平台上分别添加它们。

安卓版

将以下位置权限添加到:AndroidManifest.xml

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

如果您还想在后台访问用户的位置,请在访问后台位置之前使用该API,并在清单文件中添加后台权限:enableBackgroundMode({bool enable})

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

对于 iOS

将以下位置权限添加到:Info.plist

<key>NSLocationWhenInUseUsageDescription</key>
<string>此应用需要访问您的位置</string>

NSLocationWhenInUseUsageDescription是您需要的唯一许可。这也允许您访问后台位置,唯一需要注意的是,当应用程序在后台访问位置时,状态栏中会显示蓝色徽章。与 Android 不同,我们在其中添加了单独的权限以在后台访问用户的位置。

位置权限

我们需要在请求用户位置之前检查位置服务状态和权限状态,这可以使用以下几行代码轻松完成:

Location location = new Location();

bool _serviceEnabled;
PermissionStatus _permissionGranted;

_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
 _serviceEnabled = await location.requestService();
 if (!_serviceEnabled) {
   return null;
 }
}

_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
 _permissionGranted = await location.requestPermission();
 if (_permissionGranted != PermissionStatus.granted) {
   return null;
 }
}

首先,我们创建一个由Location()包提供的对象,location反过来为我们提供了两个有用的方法。检查设备位置是否已启用或用户是否已手动禁用它。``serviceEnabled()

对于后者,我们显示了一个原生提示,允许用户通过调用快速启用位置,然后我们再检查一次,如果他们从提示中启用了它。requestService()

一旦我们确定启用了位置服务,下一步就是通过调用它来检查我们的应用程序是否具有使用它的必要权限,这将返回.hasPermission()``PermissionStatus

PermissionStatus是可以具有以下三个值之一的枚举:

  • PermissionStatus.granted: 定位服务权限已被授予
  • PermissionStatus.denied: 定位服务权限被拒绝
  • PermissionStatus.deniedForever: 位置服务权限被用户永久拒绝。这仅适用于 iOS。在这种情况下不会显示对话框requestPermission()

如果状态为 ,我们可以通过调用显示请求位置权限的系统提示。对于 status,我们可以立即访问 location,因此我们返回一个.denied,``requestPermission()``granted``null

如果您还想在后台访问用户位置,请使用。location.enableBackgroundMode(enable: **true**)

获取当前位置

如果位置服务可用并且用户已授予位置权限,那么我们只需两行代码即可获取用户位置 - 不,我不是在开玩笑:

LocationData _locationData;
_locationData = await location.getLocation();

LocationData类提供以下位置信息:

class LocationData {
  final double latitude; // Latitude, in degrees
  final double longitude; // Longitude, in degrees
  final double accuracy; // Estimated horizontal accuracy of this location, radial, in meters
  final double altitude; // In meters above the WGS 84 reference ellipsoid
  final double speed; // In meters/second
  final double speedAccuracy; // In meters/second, always 0 on iOS
  final double heading; // Heading is the horizontal direction of travel of this device, in degrees
  final double time; // timestamp of the LocationData
  final bool isMock; // Is the location currently mocked
}

您还可以通过添加onLocationChanged侦听器在用户位置发生变化时监听位置更新来获得连续回调,这是出租车应用程序、司机/骑手应用程序等的一个很好的用例:

location.onLocationChanged.listen((LocationData currentLocation) {
  // current user location
});

注意,一旦您想停止收听更新,请不要忘记取消流订阅。

瞧!现在我们有了用户位置的当前纬度和经度值。

让我们利用这些纬度和经度值来获取用户的完整地址或反向地理编码

为此,我们将使用另一个惊人的 Flutter 包:geocode

使用 Flutter 地理编码包

设置

将依赖项添加到您的文件中:pubspec.yaml

dependencies:
    geocode: 1.0.1

获取地址

获取地址再简单不过了。就打电话吧。就是这样!带有空检查的完整函数如下所示:reverseGeocoding(latitude: lat, longitude: lang)

Future<String> _getAddress(double? lat, double? lang) async {
 if (lat == null || lang == null) return "";
 GeoCode geoCode = GeoCode();
 Address address =
     await geoCode.reverseGeocoding(latitude: lat, longitude: lang);
 return "${address.streetAddress}, ${address.city}, ${address.countryName}, ${address.postal}";
}

没那么简单!

完整的代码如下所示:

class GetUserLocation extends StatefulWidget {
 GetUserLocation({Key? key, required this.title}) : super(key: key);
 final String title;

 @override
 _GetUserLocationState createState() => _GetUserLocationState();
}

class _GetUserLocationState extends State<GetUserLocation> {
 LocationData? currentLocation;
 String address = "";

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(),
     body: Center(
       child: Padding(
         padding: EdgeInsets.all(16.0),
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: <Widget>[
             if (currentLocation != null)
               Text(
                   "Location: ${currentLocation?.latitude}, ${currentLocation?.longitude}"),
             if (currentLocation != null) Text("Address: $address"),
             MaterialButton(
               onPressed: () {
                 _getLocation().then((value) {
                   LocationData? location = value;
                   _getAddress(location?.latitude, location?.longitude)
                       .then((value) {
                     setState(() {
                       currentLocation = location;
                       address = value;
                     });
                   });
                 });
               },
               color: Colors.purple,
               child: Text(
                 "Get Location",
                 style: TextStyle(color: Colors.white),
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }

 Future<LocationData?> _getLocation() async {
   Location location = new Location();
   LocationData _locationData;

   bool _serviceEnabled;
   PermissionStatus _permissionGranted;

   _serviceEnabled = await location.serviceEnabled();
   if (!_serviceEnabled) {
     _serviceEnabled = await location.requestService();
     if (!_serviceEnabled) {
       return null;
     }
   }

   _permissionGranted = await location.hasPermission();
   if (_permissionGranted == PermissionStatus.denied) {
     _permissionGranted = await location.requestPermission();
     if (_permissionGranted != PermissionStatus.granted) {
       return null;
     }
   }

   _locationData = await location.getLocation();

   return _locationData;
 }

 Future<String> _getAddress(double? lat, double? lang) async {
   if (lat == null || lang == null) return "";
   GeoCode geoCode = GeoCode();
   Address address =
       await geoCode.reverseGeocoding(latitude: lat, longitude: lang);
   return "${address.streetAddress}, ${address.city}, ${address.countryName}, ${address.postal}";
 }
}

常见的陷阱

尽管这些软件包让我们的生活变得更轻松,而且我们不必处理在 Android 和 iOS 中本地访问位置的复杂过程,但您可能会面临很多问题。让我们来看看它们以及可以帮助您修复这些问题的步骤:

  • 应用内存泄漏:如果您一直在收听位置更新,请确保取消流订阅,一旦您想停止收听更新
  • 用户必须接受位置权限才能始终允许使用后台位置。位置权限对话框提示中未显示始终允许的 Android 11 选项。用户必须从应用程序设置中手动启用它
  • 用户可能在 iOS 上永远拒绝定位,因此不会显示要求定位权限的本机提示。确保处理这种边缘情况requestPermisssions()
  • 用户可能随时从应用程序设置中撤销位置权限,因此在访问位置数据之前,请确保在应用程序恢复时检查它们

结论

由于 Flutter 简化了访问位置,因此我们作为开发人员可能会立即将其添加到我们的应用程序中。但同时,我们需要确保我们的应用程序真正适合请求用户位置并利用它为用户增加一些价值的用例,而不是仅仅将位置数据发送到服务器。

随着即将推出的 Android 和 iOS 操作系统版本中安全性和隐私性的提高,访问位置数据而不向用户提供价值可能会导致您的应用程序被商店拒绝。有很多很好的用例,您可以使用用户位置,例如,根据用户位置为食品/外卖应用程序个性化主屏幕,该应用程序显示按用户当前位置的接近程度订购的餐厅。取件/送货应用程序是最常见的用例。

您还可以在您实际想要使用的特定屏幕上询问用户位置,而不是立即在主屏幕上询问。这使用户更清楚,并且他们不太可能拒绝位置权限。

到此这篇关于使用Flutter定位包获取地理位置的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 简单实现安卓里百度地图持续定位

    这几天自己研究了关于地手机上面开发安卓地图的问题,发现百度官方示例demo讲解百度持续定位方面还是讲解的有些不清楚,本人研究了几次之后将其弄得更详细以便于让各位方便学习,有不足之处请在评论区指出,官方示例的网址是:http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/v5-0 上面的网址已经将安卓简单配置百度地图环境讲解的很详细了,再次不做赘述了,此外,可能会有人发现 package com.example.andoridloc

  • iOS实现模拟定位功能的示例代码

    前言 App中越来越多的功能依赖用户实际的位置,例如基于用户位置提供推荐数据.基于定位判断某些功能是否可用,但是在开发调试中XCode却没有提供自定义的模拟定位的功能,所以本文主要的目的是现实一个可以在开发调试过程中随时模拟定位的功能. 思路 我们在iOS的app开发中通常采用的是CLLocationManager来获取用户当前的位置,当然也可以采用MKMapView的showUserLocation来获取用户的位置,所以我们分别针对这两种情况分析. CLLocationManager 采用CL

  • iOS开发系列--地图与定位源代码详解

    概览 现在很多社交.电商.团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用和导航应用所特有的.的确,有了地图和定位功能确实让我们的生活更加丰富多彩,极大的改变了我们的生活方式.例如你到了一个陌生的地方想要查找附近的酒店.超市等就可以打开软件搜索周边;类似的,还有很多团购软件可以根据你所在的位置自动为你推荐某些商品.总之,目前地图和定位功能已经大量引入到应用开发中.今天就和大家一起看一下iOS如何进行地图和定位开发. 定位 地图 定位 要实现地图.导航功能,往往需要先熟悉定位功能,在iO

  • iOS实现百度地图定位签到功能

    写在前面: 项目需求用到这个功能,主要目的是实现老师设置位置签到范围,学生在一定范围内进行签到的功能. 功能如下方截图: 屏幕快照 2019-01-28 上午10.29.26.png 简要介绍: 下面记录一下主要的实现流程,功能的实现主要是根据百度地图开发者官网提供的api文档,各项功能之间组合.百度地图的SDK现在分成了地图功能和定位功能两块不同的SDK,BaiduMapAPI这个是基础的地图功能,BMKLocationKit这个是定位功能.项目里实现定位签到功能用的的SDK包括上面说的这两个

  • 使用Flutter定位包获取地理位置

    目录 Flutter 中获取地理位置 先决条件 使用 Flutter 定位包 设置 位置权限 获取当前位置 使用 Flutter 地理编码包 设置 获取地址 常见的陷阱 结论 Flutter 中获取地理位置 如今,发现用户位置是移动应用程序非常常见且功能强大的用例.如果您曾经尝试过在 Android 中实现位置,您就会知道样例代码会变得多么复杂和混乱. 但这与 Flutter 不同--它有很多令人惊叹的包,可以为您抽象出样板代码,并使实现地理定位成为梦想.另一个好的方面是您可以在 Android

  • Android百度地图定位后获取周边位置的实现代码

    本文实例讲解Android百度地图定位后获取周边位置的实现代码,分享给大家供大家参考,具体内容如下 效果图: 具体代码: 1.布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical&q

  • vue引入微信sdk 实现分享朋友圈获取地理位置功能

    最近入职的公司主要做微信端的h5,所以在所难免要引用sdk.虽然官方文档写的还算清楚,但是还是有坑. 1.在index.html中 引入微信sdk <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> 2.在assets/js 下新建文件 wx.js export default { wxShowMenu: fu

  • cordova+vue+webapp使用html5获取地理位置的方法

    1.在HTML5中使用Geolocation.getCurrentPosition()方法来获取地理位置. 语法: navigator.geolocation.getCurrentPosition(success, error, options) 参数: success: 成功得到位置信息时的回调函数,使用Position 对象作为唯一的参数. error: 获取位置信息失败时的回调函数,使用 PositionError 对象作为唯一的参数,这是一个可选项. options:一个可选的Posit

  • 微信小程序获取地理位置及经纬度授权代码实例

    这篇文章主要介绍了微信小程序获取地理位置及经纬度授权代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 微信小程序获取地理位置授权,首先需要在app.json中添加配置: "permission": { "scope.userLocation": { "desc": "请确认授权" } } 获取经纬度:如果手机未开启位置信息,那么授权成功后在wx.getLocation(

  • react native 获取地理位置的方法示例

    react native 官网介绍了这个 api Geolocation 但是这个api只能返回 经纬度 所以要把经纬度 通过逆地理位置转义 http://recode.ditu.aliyun.com/jsdoc/geocode_api.html 可通过这个阿里的开放接口 在 react native 中,我们所用的是react native 自带的api定位功能,无需引入第三方js. react native 定位是通过Geolocation这个模块来实现的.想了解更多关于Geolocatio

  • python根据照片获取地理位置及泄露防御

    首先,说明一下python确实可以根据照片获取地理位置,但是也是有一定的限制条件的. 获取照片地理位置的实现思路是这样的: 通过提取照片中的经纬度信息. 然后通过经纬度信息找到具体的地理位置信息. 安装可以读取经纬度信息的python非标准库exifread pip install exifread 将该模块导入到当前代码块中. import exifread as ex 编写照片信息读取函数,获取照片中的经纬度信息. def read_image(): ''' 经纬度信息读取函数 :retur

  • SpringBoot使用ip2region获取地理位置信息的方法

    目录 1.简介 2.引入依赖 3.测试 4.测试结果 1.简介 ip2region,准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,数据库文件大小只有1.5M,提供了java,php,c,python,nodejs,golang,c#等查询绑定和Binary,B树,内存三种查询算法,仓库地址: https://gitee.com/lionsoul/ip2region 2.引入依赖 <!-- Ip地址获取 --> <dependency> <groupId>ne

  • python使用百度或高德地图获取地理位置并转换

    目录 一.地理编码与逆编码 二.高德地图地理编码 三.百度地图地理编码 四.坐标转换和空间化 总结 一.地理编码与逆编码 地理编码与逆编码表示的是地名地址与地理坐标(经纬度)互相转换的过程.其中,将地址信息映射为地理坐标的过程称之为地理编码:将地理坐标转换为地址信息的过程称之为逆地理编码.(ps:猜猜我在哪) 地理编码能对一些只有名称或地址的数据进行空间化,从而可以开展空间分析和制图,对于数据分析人员十分重要. 大量地图厂商都提供了相关的API,可以直接利用这些API进行转化.国外的如谷歌.es

  • Android编程获取地理位置的经度和纬度实例

    本文实例讲述了Android编程获取地理位置的经度和纬度.分享给大家供大家参考,具体如下: 在Android应用程序中,可以使用LocationManager来获取移动设备所在的地理位置信息.看如下实例:新建android应用程序TestLocation. 1.activity_main.xml布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_w

随机推荐