日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Flutter 中获取地理位置[Flutter专题61]

發(fā)布時(shí)間:2025/3/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter 中获取地理位置[Flutter专题61] 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大家好,我是堅(jiān)果,公眾號(hào)“堅(jiān)果前端”

Flutter 中獲取地理位置

如今,發(fā)現(xiàn)用戶位置是移動(dòng)應(yīng)用程序非常常見(jiàn)且功能強(qiáng)大的用例。如果您曾經(jīng)嘗試過(guò)在 Android 中實(shí)現(xiàn)位置,您就會(huì)知道樣例代碼會(huì)變得多么復(fù)雜和混亂。

但這與 Flutter 不同——它有很多令人驚嘆的包,可以為您抽象出樣板代碼,并使實(shí)現(xiàn)地理定位成為夢(mèng)想。另一個(gè)好的方面是您可以在 Android 和 iOS 上獲得這些功能。

讓我們快速瀏覽一下我們今天正在構(gòu)建的用于收集位置數(shù)據(jù)的內(nèi)容:

本文將帶您了解兩個(gè)最流行且易于使用的 Flutter 地理定位包。

讓我們從location開(kāi)始,這是Flutter 最喜歡的包。這很簡(jiǎn)單。只需三個(gè)簡(jiǎn)單的步驟,您就可以獲取當(dāng)前用戶位置以及處理位置權(quán)限。

先決條件

在繼續(xù)前進(jìn)之前,讓我們快速檢查一下我們需要的東西:

  • 該FlutterSDK
  • 編輯器;您可以使用 Visual Code 或 Android Studio
  • 至少對(duì) Flutter 有初級(jí)的了解

差不多就是這樣!

使用 Flutter 定位包

設(shè)置

將依賴(lài)項(xiàng)添加到您的文件中:pubspec.yaml

location: ^4.3.0

由于 Android 和 iOS 處理權(quán)限的方式不同,因此我們必須在每個(gè)平臺(tái)上分別添加它們。

安卓版

將以下位置權(quán)限添加到:AndroidManifest.xml

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

如果您還想在后臺(tái)訪問(wèn)用戶的位置,請(qǐng)?jiān)谠L問(wèn)后臺(tái)位置之前使用該API,并在清單文件中添加后臺(tái)權(quán)限:enableBackgroundMode({bool enable})

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

對(duì)于 iOS

將以下位置權(quán)限添加到:Info.plist

<key>NSLocationWhenInUseUsageDescription</key> <string>此應(yīng)用需要訪問(wèn)您的位置</string>

NSLocationWhenInUseUsageDescription是您需要的唯一許可。這也允許您訪問(wèn)后臺(tái)位置,唯一需要注意的是,當(dāng)應(yīng)用程序在后臺(tái)訪問(wèn)位置時(shí),狀態(tài)欄中會(huì)顯示藍(lán)色徽章。與 Android 不同,我們?cè)谄渲刑砑恿藛为?dú)的權(quán)限以在后臺(tái)訪問(wèn)用戶的位置。

位置權(quán)限

我們需要在請(qǐng)求用戶位置之前檢查位置服務(wù)狀態(tài)和權(quán)限狀態(tài),這可以使用以下幾行代碼輕松完成:

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

首先,我們創(chuàng)建一個(gè)由Location()包提供的對(duì)象,location反過(guò)來(lái)為我們提供了兩個(gè)有用的方法。檢查設(shè)備位置是否已啟用或用戶是否已手動(dòng)禁用它。``serviceEnabled()

對(duì)于后者,我們顯示了一個(gè)原生提示,允許用戶通過(guò)調(diào)用快速啟用位置,然后我們?cè)贆z查一次,如果他們從提示中啟用了它。requestService()

一旦我們確定啟用了位置服務(wù),下一步就是通過(guò)調(diào)用它來(lái)檢查我們的應(yīng)用程序是否具有使用它的必要權(quán)限,這將返回.hasPermission()``PermissionStatus

PermissionStatus是可以具有以下三個(gè)值之一的枚舉:

  • PermissionStatus.granted: 定位服務(wù)權(quán)限已被授予
  • PermissionStatus.denied: 定位服務(wù)權(quán)限被拒絕
  • PermissionStatus.deniedForever: 位置服務(wù)權(quán)限被用戶永久拒絕。這僅適用于 iOS。在這種情況下不會(huì)顯示對(duì)話框requestPermission()

如果狀態(tài)為 ,我們可以通過(guò)調(diào)用顯示請(qǐng)求位置權(quán)限的系統(tǒng)提示。對(duì)于 status ,我們可以立即訪問(wèn) location ,因此我們返回一個(gè).denied,``requestPermission()``granted``null

如果您還想在后臺(tái)訪問(wèn)用戶位置,請(qǐng)使用。location.enableBackgroundMode(enable: **true**)

獲取當(dāng)前位置

如果位置服務(wù)可用并且用戶已授予位置權(quán)限,那么我們只需兩行代碼即可獲取用戶位置 - 不,我不是在開(kāi)玩笑:

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

LocationData類(lèi)提供以下位置信息:

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

您還可以通過(guò)添加onLocationChanged偵聽(tīng)器在用戶位置發(fā)生變化時(shí)監(jiān)聽(tīng)位置更新來(lái)獲得連續(xù)回調(diào),這是出租車(chē)應(yīng)用程序、司機(jī)/騎手應(yīng)用程序等的一個(gè)很好的用例:

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

注意,一旦您想停止收聽(tīng)更新,請(qǐng)不要忘記取消流訂閱。

瞧!現(xiàn)在我們有了用戶位置的當(dāng)前緯度和經(jīng)度值。

讓我們利用這些緯度和經(jīng)度值來(lái)獲取用戶的完整地址或反向地理編碼。

為此,我們將使用另一個(gè)驚人的 Flutter 包:geocode。

使用 Flutter 地理編碼包

設(shè)置

將依賴(lài)項(xiàng)添加到您的文件中:pubspec.yaml

dependencies:geocode: 1.0.1

獲取地址

獲取地址再簡(jiǎn)單不過(guò)了。就打電話吧。就是這樣!帶有空檢查的完整函數(shù)如下所示: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}"; }

沒(méi)那么簡(jiǎn)單!

完整的代碼如下所示:

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 = "";@overrideWidget 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}";} }

常見(jiàn)的陷阱

盡管這些軟件包讓我們的生活變得更輕松,而且我們不必處理在 Android 和 iOS 中本地訪問(wèn)位置的復(fù)雜過(guò)程,但您可能會(huì)面臨很多問(wèn)題。讓我們來(lái)看看它們以及可以幫助您修復(fù)這些問(wèn)題的步驟:

  • 應(yīng)用內(nèi)存泄漏:如果您一直在收聽(tīng)位置更新,請(qǐng)確保取消流訂閱,一旦您想停止收聽(tīng)更新
  • 用戶必須接受位置權(quán)限才能始終允許使用后臺(tái)位置。位置權(quán)限對(duì)話框提示中未顯示始終允許的 Android 11 選項(xiàng)。用戶必須從應(yīng)用程序設(shè)置中手動(dòng)啟用它
  • 用戶可能在 iOS 上永遠(yuǎn)拒絕定位,因此不會(huì)顯示要求定位權(quán)限的本機(jī)提示。確保處理這種邊緣情況requestPermisssions()
  • 用戶可能隨時(shí)從應(yīng)用程序設(shè)置中撤銷(xiāo)位置權(quán)限,因此在訪問(wèn)位置數(shù)據(jù)之前,請(qǐng)確保在應(yīng)用程序恢復(fù)時(shí)檢查它們

結(jié)論

由于 Flutter 簡(jiǎn)化了訪問(wèn)位置,因此我們作為開(kāi)發(fā)人員可能會(huì)立即將其添加到我們的應(yīng)用程序中。但同時(shí),我們需要確保我們的應(yīng)用程序真正適合請(qǐng)求用戶位置并利用它為用戶增加一些價(jià)值的用例,而不是僅僅將位置數(shù)據(jù)發(fā)送到服務(wù)器。

隨著即將推出的 Android 和 iOS 操作系統(tǒng)版本中安全性和隱私性的提高,訪問(wèn)位置數(shù)據(jù)而不向用戶提供價(jià)值可能會(huì)導(dǎo)致您的應(yīng)用程序被商店拒絕。有很多很好的用例,您可以使用用戶位置,例如,根據(jù)用戶位置為食品/外賣(mài)應(yīng)用程序個(gè)性化主屏幕,該應(yīng)用程序顯示按用戶當(dāng)前位置的接近程度訂購(gòu)的餐廳。取件/送貨應(yīng)用程序是最常見(jiàn)的用例。

您還可以在您實(shí)際想要使用的特定屏幕上詢(xún)問(wèn)用戶位置,而不是立即在主屏幕上詢(xún)問(wèn)。這使用戶更清楚,并且他們不太可能拒絕位置權(quán)限。

感謝您的陪伴,堅(jiān)果前端的粉絲們!您可以在GitHub 上訪問(wèn)本文中使用的示例應(yīng)用程序。

總結(jié)

以上是生活随笔為你收集整理的Flutter 中获取地理位置[Flutter专题61]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。