地理位置

Flutter geolocation plugin for Android API 16+ and iOS 9+.

功能

  • 手动和自动位置权限管理
  • 当前单次位置
  • 连续位置更新,包含前台和后台选项

该插件正在积极开发中,以下功能即将推出

  • 地理编码
  • 地理围栏
  • 地点建议
  • 活动识别
  • 暴露 iOS/Android 特定 API(例如 iOS 的重要位置更新)
Android iOS
android_screenshot ios_screenshot

安装

请遵循以下说明: 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 插件全面用法的示例项目。

检查位置服务是否正常运行

API 文档: https://pub.dartlang.org/documentation/geolocation/latest/geolocation/Geolocation/isLocationOperational.html

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 插件会在您发出位置请求时自动请求权限。

API 文档: https://pub.dartlang.org/documentation/geolocation/latest/geolocation/Geolocation/requestLocationPermission.html

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 提供三种方法

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

连续位置更新

API 文档: https://pub.dartlang.org/documentation/geolocation/latest/geolocation/Geolocation/locationUpdates.html

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

GitHub

https://github.com/loup-v/geolocation