web-dev-qa-db-ja.com

ACCESS_COARSE_LOCATION権限は、Android

FusedLocationApirequestLocationUpdates()関数を使用していくつかのテストを行っています。 PRIORITY_BALANCED_POWER_ACCURACY を使用しています。都市ブロックの精度は私にとっては問題ありません。

ACCESS_FINE_LOCATION パーミッションを要求すると、GPS offで100mの精度が得られます。 GPSの精度ではなく、都市ブロックの精度が必要なので、ACCESS_COARSE_LOCATION権限のみをリクエストします。ただし、ACCESS_COARSE_LOCATION許可をリクエストすると、2 kmの精度が得られます。デバイスはWifiパーミッションを使用せず、セルタワーの精度のみを使用しているようです。

ACCESS_COARSE_LOCATION パーミッションでどのように精度を上げることができますか?

注:テストデバイスではGPSは無効になっています。

21
poiuytrez

これは興味深い問題であり、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_ACCURACYACCESS_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_POWERをAndroidManifest.xmlに保持したまま、LocationRequestAndroid.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メートルの精度であり、地図上でどれだけ近いかがわかります。

enter image description here

次に、WiFiの電源を入れました。結果は次のとおりです。

accuracy: 18.847 lat: 37.779679 lon: -122.3930918

地図で見ることができるように、文字通りスポットです:

enter image description here

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_LOCATIONPRIORITY_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を使用すると、正確な位置データを取得するという点でアプリが本当に機能しなくなるようです。

結論として、あなたが本当にできる唯一のことは、あなたとあなたのアプリのために機能する設定の最適な組み合わせに焦点を合わせることです。そして、このテストの結果があなたがその決定をするのを助けることができます。

53
Daniel Nugent

ACCESS_COARSE_LOCATION許可を要求すると、Fusion Location Clientは都市ブロックの正確さを提供します。これは意図された動作であり、ドキュメントに記載されています。ご覧ください こちら under "アプリの権限を指定してください"
提案できるのは、通常のAndroidロケーションプロバイダー(融合されたロケーションではない)を使用し、NETWORKプロバイダーにアクセスしようとすることです。これにより、WIFI精度が得られます。

3
Ohad Zadok