我正在使用requestLocationUpdates()
中的FusedLocationApi
函数进行一些测试。我正在使用PRIORITY_BALANCED_POWER_ACCURACY。城市街区精度对我来说很好。
当我申请ACCESS_FINE_LOCATION权限时,我会获得100米精度,这对于GPS
关闭非常好。由于我不需要GPS精度但是城市街区精度,我想只请求ACCESS_COARSE_LOCATION
权限。但是,当我申请ACCESS_COARSE_LOCATION
权限时,我获得了2公里的精度。似乎设备不再使用Wifi
权限,只使用单元塔精度。
如何通过ACCESS_COARSE_LOCATION权限获得更好的精确度?
注意:我的测试设备上已禁用GPS
。
答案 0 :(得分:47)
这是一个有趣的问题,我认为使用ACCESS_COARSE_LOCATION
会使用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();
}
}
的AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
的build.gradle:
compile 'com.google.android.gms:play-services:7.3.0'
我做的第一个测试是PRIORITY_BALANCED_POWER_ACCURACY
,没有WiFi。请注意,我也禁用了Always Allow Scanning
,因为它声明:
让Google位置服务和其他应用程序扫描Wi-Fi 网络,即使Wi-Fi关闭
因此,如果启用了结果,那肯定会扭曲结果。
请注意,我还在省电模式下为所有测试设置了位置模式,因此GPS收音机一直处于关闭状态。
以下是PRIORITY_BALANCED_POWER_ACCURACY
,ACCESS_COARSE_LOCATION
和无WiFi的结果:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
所以,它表示2000米精度,这里是实际坐标的距离,绿色箭头显示我实际上在哪里:
然后,我启用了WiFi,再次运行测试,令人惊讶的是,结果完全相同!
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
然后,我在LocationRequest.PRIORITY_LOW_POWER
中切换到LocationRequest
,同时将android.permission.ACCESS_COARSE_LOCATION
保留在AndroidManifest.xml中。
没有WiFi:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
使用WiFi:
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米,这是它在地图上的接近程度:
然后,我启动了WiFi,结果如下:
accuracy: 18.847 lat: 37.779679 lon: -122.3930918
正如你在地图上看到的那样,它确实存在:
在Java代码中LocationRequest
中使用的内容似乎更少,以及您在AndroidManifest.xml中使用的权限更多,因为此处的结果清楚地表明使用ACCESS_FINE_LOCATION
时打开或关闭WiFi无线电的准确性差异很大,而且一般来说也更准确。
看起来好像文档有点不合时宜,并且在使用android.permission.ACCESS_COARSE_LOCATION
时,打开或关闭WiFi无线电并不会在您的应用是唯一的制作时产生影响位置请求。
文档指出的另一件事是使用PRIORITY_BALANCED_POWER_ACCURACY
会让你的应用程序“捎带”#34;到其他应用程序的位置请求。
来自文档:
他们只会为设定的间隔指定权力责备 setInterval(long),但仍可以接收其他人触发的位置 应用程序,最高速度为setFastestInterval(long)。
因此,如果用户打开Google地图,根据文档,您的应用可以在此时获得更准确的位置。这是使用新的Fused Location Provider而不是旧API的主要方面之一,因为它可以减少您的应用程序的电池消耗量,而无需您做太多工作。
编辑:我对此功能进行了测试,以了解使用ACCESS_COARSE_LOCATION
时会发生什么。
首次测试:ACCESS_COARSE_LOCATION
,PRIORITY_BALANCED_POWER_ACCURACY
和WiFi on:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662
那把我放在水里,离我现在的位置很远。 然后,我退出了测试应用程序,启动了Google地图,它确切地定位了我,然后重新启动了测试应用程序。 测试应用程序无法从Google地图上捎带到该位置,结果与以前完全相同!
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662
我重新测试了几次,只是为了确定,但它看起来真的好像使用ACCESS_COARSE_LOCATION
也会禁用应用程序“捎带”的能力。到其他应用获得的位置。
看起来在AndroidManifest.xml中使用ACCESS_COARSE_LOCATION
在获取精确位置数据方面确实削弱了应用程序。
总之,您唯一能做的就是磨练适合您和您的应用的最佳设置组合,并希望此测试的结果可以帮助您做出决定。
答案 1 :(得分:3)
当您要求获得ACCESS_COARSE_LOCATION权限时,融合位置客户端将为您提供城市块准确性,这是预期的行为,并且已写入文档中。在“指定应用权限”下查看here
我可以建议您使用常规的android位置提供程序(不是融合位置)并尝试访问NETWORK提供程序。它应该给你WIFI准确性。