ACCESS_COARSE_LOCATION权限在Android上提供了单元格塔精度

poi*_*rez 22 permissions gps android android-location fusedlocationproviderapi

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

当我请求ACCESS_FINE_LOCATION权限时,我得到一个100米的精度,这是很好的GPS关闭.由于我不需要GPS精度但是城市街区精度,我只想请求ACCESS_COARSE_LOCATION许可.但是当我申请ACCESS_COARSE_LOCATION许可时,我得到了2公里的精度.似乎设备不再使用Wifi权限,只有单元塔精度.

如何使用ACCESS_COARSE_LOCATION权限获得更好的精度?

注意:GPS我的测试设备已禁用.

Dan*_*ent 55

这是一个有趣的问题,我的印象是ACCESS_COARSE_LOCATION使用WiFi会使用WiFi,因为这就是文档所说的内容.

ACCESS_COARSE_LOCATION各州的文件:

允许应用访问从网络位置来源(如手机信号塔和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();
    }
}
Run Code Online (Sandbox Code Playgroud)

AndroidManifest.xml中:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Run Code Online (Sandbox Code Playgroud)

的build.gradle:

compile 'com.google.android.gms:play-services:7.3.0'
Run Code Online (Sandbox Code Playgroud)

我做的第一个测试是PRIORITY_BALANCED_POWER_ACCURACY,没有WiFi.请注意,我也禁用了Always Allow Scanning,因为它声明:

即使Wi-Fi关闭,也可让Google位置服务和其他应用程序扫描Wi-Fi网络

因此,如果启用了结果,那肯定会扭曲结果.

请注意,我还在省电模式下为所有测试设置了位置模式,因此GPS收音机一直处于关闭状态.

下面是结果PRIORITY_BALANCED_POWER_ACCURACY,ACCESS_COARSE_LOCATION和没有WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
Run Code Online (Sandbox Code Playgroud)

因此,它表示2000米精度,这里是实际坐标的距离,绿色箭头显示我实际上在哪里:

在此输入图像描述

然后,我启用了WiFi,再次运行测试,令人惊讶的是,结果完全相同!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
Run Code Online (Sandbox Code Playgroud)

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

没有WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
Run Code Online (Sandbox Code Playgroud)

有WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
Run Code Online (Sandbox Code Playgroud)

结果再次完全相同!使用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" />
Run Code Online (Sandbox Code Playgroud)

首次测试,没有WiFi:

accuracy: 826.0 lat: 37.7825458 lon: -122.3948752
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

然后,我启动了WiFi,结果如下:

accuracy: 18.847 lat: 37.779679 lon: -122.3930918
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

似乎你LocationRequest在Java代码中使用的更少,以及你在AndroidManifest.xml中使用的权限更多,因为这里的结果清楚地表明,在使用时ACCESS_FINE_LOCATION,开启或关闭WiFi无线电产生了巨大的差异.准确性,一般来说也更准确.

当然看起来好像文档有点突破,并且在使用时android.permission.ACCESS_COARSE_LOCATION,打开或关闭WiFi无线电并不会对您的应用程序是唯一提出位置请求的人产生影响.

文档说明的另一件事是,使用PRIORITY_BALANCED_POWER_ACCURACY将让您的应用程序"捎带"到其他应用程序发出的位置请求.从文档:

它们仅被设置为由setInterval(long)设置的间隔的权限,但仍然可以以高达setFastestInterval(long)的速率接收由其他应用程序触发的位置.

因此,如果用户打开Goog​​le地图,根据文档,您的应用可以在此时获得更准确的位置.这是使用新的Fused Location Provider而不是旧API的主要方面之一,因为它可以减少您的应用程序的电池消耗量,而无需您做太多工作.

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

第一次测试:ACCESS_COARSE_LOCATION,PRIORITY_BALANCED_POWER_ACCURACY和WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662
Run Code Online (Sandbox Code Playgroud)

这让我在水中,离我现在的位置很远.然后,我退出了测试应用程序,启动了Google地图,它确切地定位了我,然后重新启动了测试应用程序.测试应用程序无法从Google地图上捎带到该位置,结果与以前完全相同!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662
Run Code Online (Sandbox Code Playgroud)

我重新测试了几次,只是为了确定,但它看起来像使用ACCESS_COARSE_LOCATION也会禁用应用程序"捎带"到其他应用程序获取的位置的能力.

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

总而言之,您唯一能做的就是磨练适合您和您的应用程序的最佳设置组合,并希望此测试的结果可以帮助您做出决定.