Android GPS定位精度问题

Posted

技术标签:

【中文标题】Android GPS定位精度问题【英文标题】:Android GPS location accuracy issue 【发布时间】:2017-07-10 17:42:38 【问题描述】:

我正在开发 android 中的 gps 跟踪应用程序。这是我的代码架构:

    BackgroundSyncService :用于获取位置更新的服务类。这里初始化了 GoogleApiClient 并实现了其他与 Location 相关的方法。 AppRunCheckerReceiver :一个 BroadcastReceiver 类,它将检查我的BackgroundSyncService 是否在某个时间间隔内运行。如果它停止了,它就会开始。 GpsEnableReceiver : 如果 gps 状态发生变化,它将触发一个 BroadcastReceiver。它将检查我的BackgroundSyncService 是否在某个时间间隔内运行。如果它停止了,它就会开始。 InternetConnectionStateReceiver :当 Internet 状态发生变化时会触发的 BroadcastReceiver。它将检查我的BackgroundSyncService 是否在某个时间间隔内运行。如果停止,则开始。

在我的 BackgroundSyncService 服务中,我使用这种方式初始化 GoogleApiClient:

public void setLocationLocationRequest() 

        try 
            googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).addApi(com.google.android.gms.location.LocationServices.API).build();

            locationRequest = new LocationRequest();
            locationRequest.setInterval(3000);
            locationRequest.setFastestInterval(3000);
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            googleApiClient.connect();
         catch (Exception e) 

    

这里的准确率是LocationRequest.PRIORITY_HIGH_ACCURACY,间隔是

locationRequest.setInterval(3000)

here 是 GoogleApiClient 的实现代码。

This应用GPS信息部分包含纬度经度和精度参数

我的发现:onLocationChanged(Location location) 方法中,我以这种方式检查Location 对象的准确性:location.getAccuracy()。这里如果精度小于50米,我接受。

在 85% 的情况下,它就像一个魅力。它从 GPS 向我发送了确切的位置。但在 15% 的情况下,它会向我发送不准确的位置,例如超过 300 米。

15% 的设备是低成本的中国品牌手机。

我的问题:

    如何使准确度接近 99%。我的代码架构有什么问题吗? GPS 精度是否取决于设备配置?如果是,那么我可以为低配置设备做什么? Uber、Go-JEK 等拼车应用程序如何适用于所有设备?他们是否只有 GPS 的额外编码? 我的申请是针对孟加拉国的。这里的网速很慢。它对 GPS 精度有负面影响吗?

提前感谢这个帖子。也很抱歉英语不好。

【问题讨论】:

你试过FusedLocationProviderAPI吗? 感谢@Piyush,我使用它但没有改进。 当您说它适用于 85% 的情况时 - 您是指您获得的 85% 的位置,还是 85% 的设备?关于q。 4 - 网速与 GPS 无关。这是两个不同的系统。 你的问题很好,但我怀疑开发人员会重新投入他们为实现这件事所做的所有努力来制作你的应用程序,那么当然没有竞争。是的 gps 准确性与设备有关检查设备规格上的网络部分,可以了解他们使用什么卫星系统来获取 GPS。互联网速度与 GPS 无关,您甚至可以关闭互联网并工作。这是阅读所有内容的主线程,它将一定能帮到你***.com/questions/3145089/… 他们没什么特别的,只有developer.android.com/training/location/retrieve-current.html 【参考方案1】:

位置更新可以通过以下方式完成:

    您从 GPS 获得的位置比您从网络获得的位置更准确,因此如果您需要准确度,请使用 GPS

    对此不确定,但我认为它与上下文有关,您想要什么类型的位置,如您想要的准确性或最快的位置,因此根据选择您的提供商

    FusedLocation 提供程序是目前在 android 上获取位置的最有效和最有效的解决方案,它从不同来源收集位置数据,并根据传递的参数,如您希望更新位置的时间,您是否需要高精度等。它为您提供最佳位置。

    是的,您应该使用 FusedLocationProvider 来获取 android 上的位置,因为 google 也建议这样做,它是目前在 android 上获取位置的最有效和最有效的方式。

你为什么不尝试创建Criteria.ACCURACY_HIGH

表示高精度要求的常数 - 可用于水平、高度、速度或方位精度。对于水平和垂直位置,这大致对应于小于 100 米的精度。

Android 试图向我们掩盖硬件的真实性,但实际上只有两个位置提供程序:GPS 和网络。 GPS定位很慢,并非所有设备都有,但它是准确的。网络定位速度更快,几乎所有设备都支持,但准确度较低。

Google 通过fused location provider.改进了其地图和位置管理

与融合位置提供程序交互的主要入口点。这些方法必须与 GoogleApiClient 一起使用。


代码:

 new GoogleApiClient.Builder(context)
         .addApi(LocationServices.API)
         .addConnectionCallbacks(this)
         .addOnConnectionFailedListener(this)
         .build()

gps –>(GPS、AGPS): GPS 位置提供商的名称。该提供商使用卫星确定位置。根据 条件下,此提供程序可能需要一段时间才能返回位置修复。 需要权限 android.permission.ACCESS_FINE_LOCATION。

网络 –> (AGPS、CellID、WiFi MACID):网络位置提供商的名称。 该提供商根据手机信号塔的可用性确定位置 和 WiFi 接入点。通过网络检索结果 抬头。需要任一权限 android.permission.ACCESS_COARSE_LOCATION 或 android.permission.ACCESS_FINE_LOCATION。


其他选项:

getLastKnownLocation()

getLastKnownLocation() 这将返回最后一个已知位置...在您重新安装应用程序后,它不会有任何最后一个已知位置...所以它会导致 NPE...而不是使用下面的代码

public Location getLocation() 
    try 
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) 
            // no network provider is enabled
         else 
            this.canGetLocation = true;
            //here is the if-else change so code avoids falling into both loops
         // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) 
                if (location == null) 
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS", "GPS Enabled");
                    if (locationManager != null) 
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) 
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        
                    
                
             else if (isNetworkEnabled) 
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network Enabled");
                if (locationManager != null) 
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) 
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    
                
            
        

     catch (Exception e) 
        e.printStackTrace();
    

    return location;

检查几个我发现的最佳示例:

http://rdcworld-android.blogspot.in/2012/01/get-current-location-coordinates-city.html

https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi

https://developer.android.com/reference/android/location/LocationManager.html

https://demonuts.com/current-gps-location/

https://developer.android.com/training/location/retrieve-current.html

它对我有用……应该也对你有用……

【讨论】:

@user2450263 根据代码,它将首先检查 GPS,如果找到,它将仅从 GPS 获取位置。 不正确,根据代码它会落入else循环,无论它要使用哪个位置,都要经过两个if循环,这是从哪里提升代码的相同问题:) 它将如何进入两个条件我有if() 然后else if() 它会检查条件是否为真然后它会进入它所以它永远不会调用else if() 虽然OP已检查并赞成/接受此逻辑。我在这里休息谢谢!!!! @user2450263 它应该是怎样的?您有 edited 并在 Network 之前制作了更多 GPS,因此现在它将返回更准确的位置。 代码在 else 部分有 2 个 if 条件,第一个用于网络,第二个用于 gps,这意味着如果两者都启用,则 2 个 if 语句为真,代码将遍历它们——不必要.我将 GPS 部分移到上面并为网络添加了 else-if,这样如果两者都启用,代码将仅通过 gps 遍历并为您获取更准确的位置。希望这也能回答@Gattsu【参考方案2】:
    如何使准确度接近 99%。我的代码架构有什么问题吗?

这是现实生活中的场景。您无法确保所有位置提供程序都能按预期工作。你应该要求最好的位置。

    a) GPS 精度是否取决于设备配置?

是的。一些设备可能具有较旧的 GPS 芯片组,只能跟踪 GPS 信号(美国),因为还有其他定位系统,如 Galileo(欧洲)、GLONASS(俄罗斯)、QZSS(日本)和北斗(中国)。对这些类型的芯片组支持越多,您跟踪更多卫星从而定位的机会就越大。此外,TTFF(首次修复时间)取决于 GPS 接收器有多少个通道。

b) 如果是,那么我可以为低配置设备做什么?

由于这是一个硬件问题,您无法在此处执行任何操作。但其他位置来源可以弥补 GPS 数据的不足,例如 AGPS(辅助 GPS)、wifi 和蜂窝定位。还有一些付费选项提供了一个数据库,可以使用 wifi 接入点和 cellids 来定位您的设备(他们声称他们在 wifi 上提供了最佳解决方案,但我不确定,因为我不使用它。您可以查看 http://combain.com)。 Wifi 和 cellid 还取决于周围有多少可用的 wifi 接入点和手机信号塔以及它们的距离(信号强度)。如果你需要 50m 的精度,蜂窝定位无关紧要,但 wifi 有机会接近这个值。

2009 年的一些研究结果 [3]

带 A-GPS 的 3G iPhone ~ 8 米 3G iPhone w/wifi ~ 74 米 3G iPhone w/蜂窝定位 ~ 600 米
    Uber、Go-JEK 等拼车应用程序如何适用于所有设备?他们是否有额外的 GPS 编码?

他们可能有特定的位置策略,但它将基于在 GPS 中断期间使用其他来源。

    我的申请是针对孟加拉国的。这里的网速很慢。它对 GPS 精度有负面影响吗?

其他答案声称互联网与 GPS 无关。是的,它确实与 GPS 无关,而是与位置有关。 AGPS 使用互联网获取 3 种类型的数据(卫星信号、年历和星历),这有助于 GPS 更快地提供定位。如果星历表和历书已过时或设备从先前的定位移动了数百公里,则称为冷启动,并且在没有 AGPS 的情况下大约需要 12-15 分钟。

Fused location provider 已经知道如何使用这些配置提供最佳解决方案,所以你应该祝福它。

参考资料:

[1]http://gpssystems.net/agps/ [2]http://gpsinformation.net/main/almanac.txt [3] https://communityhealthmaps.nlm.nih.gov/2014/07/07/how-accurate-is-the-gps-on-my-smart-phone-part-2/

【讨论】:

【参考方案3】:

+1 用于相关描述。 我希望我们为您的问题找到最佳答案,并随着时间的推移而改进,据我所知..这里不会只有一个正确的答案。

第一,(第二)

    如何使准确度接近 99%。我的代码架构有问题吗?

    GPS 精度是否取决于设备配置?如果是,那么我可以为低配置设备做什么?

设备配置和代码架构在这里都很重要。如果您的成功率已经达到 85%,那么我认为代码架构还可以。 就 GPS 而言,在设备配置和准确性方面,视线是一个重要因素。 尽管低成本的移动设备可以返回具有清晰视线的准确位置。您可以尝试多运行 2 个周期/等待以获得更高的准确度。

在最坏的情况下,无论其价值如何,您还可以尝试使用LocationManager 和 GPS 提供程序技术检索位置,该技术可作为 15% 的后备,只是为了比较并确保您使用的是最准确的位置你可以得到。 Location Strategies 写成

在大多数情况下,您将获得更好的电池性能,以及更多 适当的准确性,通过使用位置服务 API。

    Uber、Go-JEK 等拼车应用程序如何适用于所有设备?他们是否有额外的 GPS 编码? 它们确实有效,但对于应用程序中收到的位置并不总是最准确。如果我们的开发人员有任何位置黑客,我们需要找到它们,也许是第 5 页的谷歌搜索结果:) 或者从开源环境中受益。对我来说,最佳实践和 android repo 链接就足够了。你已经关注了Receive location updates这样的帖子

    我的申请是针对孟加拉国的。这里的网速很慢。它对 GPS 精度有负面影响吗? 互联网与LocationManager + GPS_PROVIDER没有关系

【讨论】:

以上是关于Android GPS定位精度问题的主要内容,如果未能解决你的问题,请参考以下文章

Android 定位模式,无 GPS,AOSP 中的选项

具体解释Android定位

《第一行代码》Android特色开发,基于位置服务,出现的问题

Android GPS定位速度不可靠

仅使用 GPS 无线电进行高精度 webkit 地理定位

Android附近基站+Wifi+IP+GPS多渠道定位方案