android - ACCESS_COARSE_LOCATION 权限可在 Android 上提供手机信号塔精度

标签 android permissions gps android-location fusedlocationproviderapi

我正在使用 requestLocationUpdates() 进行一些测试来自 FusedLocationApi 的函数.我正在使用 PRIORITY_BALANCED_POWER_ACCURACY .城市街区的精度对我来说很好。

当我请求 ACCESS_FINE_LOCATION许可,我得到了大约 100m 的精度,这对 GPS 来说非常有用离开。因为我不需要 GPS 精度,但需要城市街区精度,我只想请求 ACCESS_COARSE_LOCATION允许。但是,当我请求 ACCESS_COARSE_LOCATION许可,我得到了 2 公里的精度。设备似乎不再使用 Wifi许可,只有一个手机信号塔精度。

如何使用 ACCESS_COARSE_LOCATION 获得更好的精度?允许?

注:GPS在我的测试设备上被禁用。

最佳答案

这是一个有趣的问题,我的印象是使用 ACCESS_COARSE_LOCATION将使用 WiFi,因为这就是文档所说的。
ACCESS_COARSE_LOCATION 的文档状态:

Allows an app to access approximate location derived from network location sources such as cell towers and Wi-Fi.



因此,我对其进行了测试,结果令人惊讶。

这是我用来测试的代码:
public class MainActivity extends Activity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onPause(){
        super.onPause();
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
        //mLocationRequest.setSmallestDisplacement(0.1F);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {

        Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude());

        Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();
    }
}

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

构建.gradle:
compile 'com.google.android.gms:play-services:7.3.0'

我做的第一个测试是使用 PRIORITY_BALANCED_POWER_ACCURACY ,并且没有 WiFi。请注意,我还禁用了 Always Allow Scanning ,因为它指出:

Let Google Location Service and other applications scan for Wi-Fi networks, even when Wi-Fi is off



因此,如果启用它,那肯定会扭曲结果。

请注意,我还在所有测试中都将位置模式设置为省电模式,因此 GPS radio 一直处于关闭状态。

以下是 PRIORITY_BALANCED_POWER_ACCURACY 的结果, ACCESS_COARSE_LOCATION ,并且没有 WiFi:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

所以,它说 2000 米的精度,这里是实际坐标有多远,绿色箭头显示我实际在哪里:

enter image description here

然后,我启用了WiFi,再次运行测试,结果竟然一模一样!
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

然后,我切换到LocationRequest.PRIORITY_LOW_POWERLocationRequest同时保持android.permission.ACCESS_COARSE_LOCATION在 AndroidManifest.xml 中。

没有无线网络:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

使用无线网络:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021

结果又是一模一样!
使用 PRIORITY_LOW_POWER与使用 PRIORITY_BALANCED_POWER_ACCURACY 的结果相同,因为 WiFi 状态似乎对坐标的准确性没有任何影响。

然后,为了覆盖所有的基础,我改回 LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY ,并将 AndroidManifest.xml 切换为 ACCESS_FINE_LOCATION :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

第一次测试,没有WiFi:
accuracy: 826.0 lat: 37.7825458 lon: -122.3948752

所以,它说的准确度是 826 米,这是它在 map 上的接近程度:

enter image description here

然后,我打开WiFi,结果如下:
accuracy: 18.847 lat: 37.779679 lon: -122.3930918

正如您在 map 上看到的那样,它确实是正确的:

enter image description here

您在 LocationRequest 中使用的内容似乎无关紧要。在 Java 代码中,以及更多您在 AndroidManifest.xml 中使用的权限,因为这里的结果清楚地表明使用 ACCESS_FINE_LOCATION 时,打开或关闭 WiFi radio 对准确性有很大影响,而且总体上也更准确。

看起来文档似乎有点误导,而且在使用 android.permission.ACCESS_COARSE_LOCATION 时,当您的应用程序是唯一发出位置请求的应用程序时,打开或关闭 WiFi radio 并没有什么不同。

文档指出的另一件事是使用 PRIORITY_BALANCED_POWER_ACCURACY会让您的应用“搭载”其他应用发出的位置请求。
从文档中:

They will only be assigned power blame for the interval set by setInterval(long), but can still receive locations triggered by other applications at a rate up to setFastestInterval(long).



因此,如果用户打开 Google map ,根据文档,您的应用程序可以在该点获得更准确的位置。这是使用新的 Fused Location Provider 而不是旧 API 的主要优点之一,因为它可以减少应用程序的电池消耗量,而无需您做太多工作。

编辑:我对此功能进行了测试,看看使用 ACCESS_COARSE_LOCATION 时会发生什么.

第一次测试:ACCESS_COARSE_LOCATION , PRIORITY_BALANCED_POWER_ACCURACY ,并开启 WiFi:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662

这让我在水中,离我现在的位置很远。
然后,我退出了测试应用程序,启动了谷歌地图,它准确地定位了我所在的位置,然后重新启动了测试应用程序。
测试应用程序无法从谷歌地图捎带回位置,结果和以前完全一样!
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662

为了确定,我重新测试了几次,但它看起来真的像使用 ACCESS_COARSE_LOCATION还禁用应用程序“搭载”到其他应用程序获得的位置的能力。

看起来像使用 ACCESS_COARSE_LOCATION AndroidManifest.xml 在获取精确位置数据方面确实削弱了应用程序。

总之,你唯一能做的就是磨练适合你和你的应用的最佳设置组合,希望这个测试的结果可以帮助你做出这个决定。

关于android - ACCESS_COARSE_LOCATION 权限可在 Android 上提供手机信号塔精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30191047/

相关文章:

azure - Get-AzADAppPermission Id 转换器

onRequestPermissionsResult() 中的 Android java.lang.IllegalStateException

c - 通过 GPS 坐标测量距离

ios - 计算短距离行驶 IOS

android - 如何在整个应用程序中保持 XMPP 连接有效?

android - 如何在约束布局中创建水平 ScrollView

android - 如何在已经激活的应用程序中开发一项功能(需要 Facebook 的 user_friends 许可)?

android - Android GPS 定位的 getAltitude() 是如何工作的

java - 根据mapbox map android上的用户导航旋转标记(箭头)

android - 在 NestedScrollView 用完滚动内容后停止 CollapsingToolbar 折叠