IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 关于flutter-geolocator库使用问题,解决android使用LocationManager定位问题 -> 正文阅读

[移动开发]关于flutter-geolocator库使用问题,解决android使用LocationManager定位问题


有需要直接定位到最下面。

相关知识

  • geolocator flutter一个比较好用的定位库
  • android原生提供的LocationManager,常用的定位库
  • 谷歌定位服务Google Location Service,需要引入google服务
    已经具备定位权限,并用户同意授权。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

问题

import 'package:geolocator/geolocator.dart';

Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

在使用flutter-geolocator遇到的问题。有的手机获取定位很快,有的手机半天没有定位结果,定位很慢。

现象

查看flutter-geolocator源码,发现内部使用了两种定位方式。一种是android原生提供的LocationManager,另一种是谷歌定位服务Google Location Service,需要引入google服务。
1.在使用Google Location Service的方式获取定位,没有翻墙,没有回调。
2.在使用原生LocationManager的方式获取定位,有两种情况,一种是网络定位、一种是GPS定位。使用网络定位,但没有连接网络,没回调。使用PGS定位,在室内测试没回调。

分析问题

在Flutter调用Geolocator.getCurrentPosition方法

Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

会进入到原生,具体使用哪个方式来获取定位,从这里可以知道

  1. 设置属性forceAndroidLocationManager为true,则会使用android原生的LocationManager获取定位信息。
    forceAndroidLocationManager为false,则会判断google服务是否可用
  2. google服务可用,则会使用Google Location Service的方式,这里就是FusedLocationClient封装了方法。
  3. google服务不可用,也会使用android原生的LocationManager获取定位信息。
public LocationClient createLocationClient(
      Context context,
      boolean forceAndroidLocationManager,
      @Nullable LocationOptions locationOptions) {
    if (forceAndroidLocationManager) {
      return new LocationManagerClient(context, locationOptions);
    }

    return isGooglePlayServicesAvailable(context)
        ? new FusedLocationClient(context, locationOptions)
        : new LocationManagerClient(context, locationOptions);
  }

解决问题

为了在国内外都能正常使用,就不能依赖google服务,所以这里我们打将forceAndroidLocationManager属性设置为true。

Geolocator.getCurrentPosition(forceAndroidLocationManager: true)

这样就会使用Android原生的LocationManager定位,但又有新的问题,上面说了,LocationManager有两种情况,一种是网络定位、一种是GPS定位。使用GPS的话,在室内会非常慢,这肯定是不太想要的,所以我们只要使用网络定位的方式就可以很好的解决问题。

定位到LocationManagerClient类,getBestProvider方法。发现代码的实现方式,先通过locationManager.getProviders获取支持的定位方式。

if (Strings.isEmptyOrWhitespace(provider)) {
    List<String> providers = locationManager.getProviders(true);
    if (providers.size() > 0) provider = providers.get(0);
}

官方提供了几种Provider:

  1. LocationManager.NETWORK_PROVIDER,网络定位,网络定位则更具有实时性,在精度要求不高以及室内
  2. LocationManager.GPS_PROVIDER,GPS定位,首次采集数据较慢,定位精度高
  3. LocationManager.PASSIVE_PROVIDER,被动定位,被动定位并不会做任何获取位置信息的尝试,它只是被动的接收位置信息的更新,只有其他应用使用了网络定位或GPS定位获取到了新的位置信息后,被动定位的监听者才能获取当前位置。

修改源码

官方实现方式是直接获取第一个定位方式,如果这个方式刚好是GPS定位,那在室内调试的时候,半天获取不到数据。只要改成,都使用网络定位的方式就好了。

      Location currentLocation = locationManager.getLastKnownLocation(provider);
      List<String> providers = locationManager.getProviders(true);
    
      if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
          provider = LocationManager.NETWORK_PROVIDER;
      } else if (providers.contains(LocationManager.GPS_PROVIDER)) {
          provider = LocationManager.GPS_PROVIDER;
      }

如果存在NETWORK_PROVIDER,就使用网络定位的方式。这样就解决问题了。

再进行一些其他优化,源码中onLocationChanged回调函数,是获取定位的回调,里面还进行了一些误差范围的限制,由于使用网络定位,误差可能会比原本的限制值偏大,所以也进行了一点微调。
在精确度中,加入一个lowest:1000的值。

private static float accuracyToFloat(LocationAccuracy accuracy) {
    switch (accuracy) {
      case lowest:
          return 1000;
      case low:
        return 500;
      case medium:
        return 250;
      case best:
      case bestForNavigation:
        return 50;
      default:
        return 100;
    }
  }

使用方式

pubspec.yaml

dependencies:
  flutter-geolocator:
    git:
      url: "https://github.com/Super-Bin/flutter-geolocator"
	  ref: geolocator_v7.0.3_zzb_0421

flutter调用

Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.lowest,
                      forceAndroidLocationManager: true)

最好先把代码拉下来,在demo运行验证通过了再集成到项目中。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 10:01:16  更:2021-11-27 10:03:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:33:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码