怎么使用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
如果您还想在后台访问用户的位置,请在访问后台位置之前使用该API,并在清单文件中添加后台权限:enableBackgroundMode({bool enable})
对于 iOS
将以下位置权限添加到:Info.plist
NSLocationWhenInUseUsageDescription 此应用需要访问您的位置
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_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{ 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: [ 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 _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 _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定位包获取地理位置"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!