地理位置
Flutter geolocation plugin for Android API 16+ and iOS 9+.
功能
- 手动和自动位置权限管理
- 当前单次位置
- 连续位置更新,包含前台和后台选项
该插件正在积极开发中,以下功能即将推出
- 地理编码
- 地理围栏
- 地点建议
- 活动识别
- 暴露 iOS/Android 特定 API(例如 iOS 的重要位置更新)
| Android | iOS |
|---|---|
![]() |
![]() |
安装
请遵循以下说明: https://pub.dev/packages/geolocation#-installing-tab-
Android
Geolocation 依赖于 AndroidX。请确保在 'android/gradle.properties' 中添加以下设置
android.useAndroidX=true
android.enableJetifier=true
Permission
Android 和 iOS 都需要在配置文件中声明位置权限。
对于 iOS
iOS 提供了两种位置权限:“使用期间”和“始终”。
如果您不确定要为您的用途选择哪种权限,请参阅
https://developer.apple.com/documentation/corelocation/choosing_the_authorization_level_for_location_services
您需要在 ios/Runner/Info.plist 中声明所需权限的描述
<dict>
<!-- for iOS 11 + -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>Reason why app needs location</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Reason why app needs location</string>
<!-- additionally for iOS 9/10, if you need always permission -->
<key>NSLocationAlwaysUsageDescription</key>
<string>Reason why app needs location</string>
...
</dict>
对于 Android
Android 提供了两种位置权限:“粗略”和“精确”。
粗略位置允许使用 Wi-Fi 等传感器获取近似位置,而精确位置则使用 GPS 获取最准确的位置(除了粗略)。
您需要在 android/app/src/main/AndroidManifest.xml 中声明这两种权限之一
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- or -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
请注意,ACCESS_FINE_LOCATION 权限已包含 ACCESS_COARSE_LOCATION。
API
有关所有用法的更完整文档,请查看 API 文档
https://pub.dartlang.org/documentation/geolocation/latest/geolocation/geolocation-library.html
您还可以查看展示 Geolocation 插件全面用法的示例项目。
检查位置服务是否正常运行
final GeolocationResult result = await Geolocation.isLocationOperational();
if(result.isSuccessful) {
// location service is enabled, and location permission is granted
} else {
// location service is not enabled, restricted, or location permission is denied
}
请求位置权限
在 Android (api 23+) 和 iOS 上,应用程序需要在运行时请求位置权限。
注意:您无需手动请求权限。
如果需要,Geolocation 插件会在您发出位置请求时自动请求权限。
final GeolocationResult result = await Geolocation.requestLocationPermission(
const LocationPermission(
android: LocationPermissionAndroid.fine,
ios: LocationPermissionIOS.always,
),
openSettingsIfDenied: true,
);
if(result.isSuccessful) {
// location permission is granted (or was already granted before making the request)
} else {
// location permission is not granted
// user might have denied, but it's also possible that location service is not enabled, restricted, and user never saw the permission request dialog. Check the result.error.type for details.
}
获取当前单次位置
Geolocation 提供三种方法
- 最后已知位置(Android 上最佳)
https://pub.dartlang.org/documentation/geolocation/latest/geolocation/Geolocation/lastKnownLocation.html - 单次位置更新(iOS 上最佳)
https://pub.dartlang.org/documentation/geolocation/latest/geolocation/Geolocation/singleLocationUpdate.html - 当前位置(结合两者优点,尝试检索 Android 上的最后已知位置,否则请求单次位置更新)
https://pub.dartlang.org/documentation/geolocation/latest/geolocation/Geolocation/currentLocation.html
// get last known location, which is a future rather than a stream (best for android)
LocationResult result = await Geolocation.lastKnownLocation();
// force a single location update (best for ios)
StreamSubscription<LocationResult> subscription = Geolocation.currentLocation(accuracy: LocationAccuracy.best).listen((result) {
// todo with result
});
// best option for most cases
StreamSubscription<LocationResult> subscription = Geolocation.currentLocation(accuracy: LocationAccuracy.best).listen((result) {
if(result.isSuccessful) {
Double latitude = result.location.latitude;
// todo with result
}
});
连续位置更新
StreamSubscription<LocationResult> subscription = Geolocation.locationUpdates(
accuracy: LocationAccuracy.best,
displacementFilter: 10.0, // in meters
inBackground: true, // by default, location updates will pause when app is inactive (in background). Set to `true` to continue updates in background.
)
.listen((result) {
if(result.isSuccessful) {
// todo with result
}
});
// cancelling subscription will also stop the ongoing location request
subscription.cancel();
处理位置结果
位置请求返回 LocationResult future 或 LocationResult 的流。
API 文档: https://pub.dartlang.org/documentation/geolocation/latest/geolocation/LocationResult-class.html
LocationResult result = await Geolocation.lastKnownLocation();
if (result.isSuccessful) {
// location request successful, location is guaranteed to not be null
double lat = result.location.latitude;
double lng = result.location.longitude;
} else {
switch (result.error.type) {
case GeolocationResultErrorType.runtime:
// runtime error, check result.error.message
break;
case GeolocationResultErrorType.locationNotFound:
// location request did not return any result
break;
case GeolocationResultErrorType.serviceDisabled:
// location services disabled on device
// might be that GPS is turned off, or parental control (android)
break;
case GeolocationResultErrorType.permissionNotGranted:
// location has not been requested yet
// app must request permission in order to access the location
break;
case GeolocationResultErrorType.permissionDenied:
// user denied the location permission for the app
// rejection is final on iOS, and can be on Android if user checks `don't ask again`
// user will need to manually allow the app from the settings, see requestLocationPermission(openSettingsIfDenied: true)
break;
case GeolocationResultErrorType.playServicesUnavailable:
// android only
// result.error.additionalInfo contains more details on the play services error
switch(result.error.additionalInfo as GeolocationAndroidPlayServices) {
// do something, like showing a dialog inviting the user to install/update play services
case GeolocationAndroidPlayServices.missing:
case GeolocationAndroidPlayServices.updating:
case GeolocationAndroidPlayServices.versionUpdateRequired:
case GeolocationAndroidPlayServices.disabled:
case GeolocationAndroidPlayServices.invalid:
}
break;
}
}
作者
Geolocation 插件由 Loup 开发,Loup 是一家位于蒙特利尔和巴黎的移动开发工作室。
您可以联系我们: [email protected]
贡献者
- lukaspili
- mit-mit
- shehabic-work
- Abgaryan
- shehabic
- alfanhui

