FusedLocationApi
のrequestLocationUpdates()
関数を使用していくつかのテストを行っています。 PRIORITY_BALANCED_POWER_ACCURACY を使用しています。都市ブロックの精度は私にとっては問題ありません。
ACCESS_FINE_LOCATION パーミッションを要求すると、GPS
offで100mの精度が得られます。 GPSの精度ではなく、都市ブロックの精度が必要なので、ACCESS_COARSE_LOCATION
権限のみをリクエストします。ただし、ACCESS_COARSE_LOCATION
許可をリクエストすると、2 kmの精度が得られます。デバイスはWifi
パーミッションを使用せず、セルタワーの精度のみを使用しているようです。
ACCESS_COARSE_LOCATION パーミッションでどのように精度を上げることができますか?
注:テストデバイスではGPS
は無効になっています。
これは興味深い問題であり、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
も無効になっていることに注意してください。
Wi-Fiがオフの場合でも、Googleロケーションサービスと他のアプリケーションが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
をAndroidManifest.xmlに保持したまま、LocationRequest
でAndroid.permission.ACCESS_COARSE_LOCATION
に切り替えました。
WiFiなし:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
WiFiを使用する場合:
accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021
結果はまったく同じでした! PRIORITY_LOW_POWER
を使用すると、WiFi状態が座標の精度に影響を与えないように見えるという点で、PRIORITY_BALANCED_POWER_ACCURACY
を使用した場合と同じ結果が得られました。
次に、すべてのベースをカバーするために、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ラジオをオンまたはオフにしても、アプリが位置情報のリクエストを行う唯一の場合には違いはありません。
ドキュメントに記載されているもう1つのことは、PRIORITY_BALANCED_POWER_ACCURACY
を使用すると、アプリが他のアプリによって行われた位置情報要求に「ピギーバック」できることです。ドキュメントから:
SetInterval(long)、ただし、他のアプリケーションによってトリガーされた場所を引き続き受信できます setFastestInterval(long)までのレートで設定された間隔に対してのみ、非難が割り当てられます。
そのため、ユーザーがGoogleマップを開くと、ドキュメントによると、アプリはその時点でより正確な位置を取得できます。これは、古いAPIよりも新しいFused Location Providerを使用することの大きな利点の1つです。これは、ユーザーの多くの作業なしでアプリのバッテリー消費量を減らすためです。
編集:ACCESS_COARSE_LOCATION
の使用中に何が起こるかを確認するために、この機能のテストを実行しました。
最初のテスト:ACCESS_COARSE_LOCATION
、PRIORITY_BALANCED_POWER_ACCURACY
、およびWiFiオン:
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
を使用すると、正確な位置データを取得するという点でアプリが本当に機能しなくなるようです。
結論として、あなたが本当にできる唯一のことは、あなたとあなたのアプリのために機能する設定の最適な組み合わせに焦点を合わせることです。そして、このテストの結果があなたがその決定をするのを助けることができます。
ACCESS_COARSE_LOCATION許可を要求すると、Fusion Location Clientは都市ブロックの正確さを提供します。これは意図された動作であり、ドキュメントに記載されています。ご覧ください こちら under "アプリの権限を指定してください"
提案できるのは、通常のAndroidロケーションプロバイダー(融合されたロケーションではない)を使用し、NETWORKプロバイダーにアクセスしようとすることです。これにより、WIFI精度が得られます。