Подтвердить что ты не робот

Разрешение ACCESS_COARSE_LOCATION дает точность ячеек на Android

Я делаю некоторые тесты с помощью функции requestLocationUpdates() из FusedLocationApi. Я использую PRIORITY_BALANCED_POWER_ACCURACY. Точная точность городского квартала подходит для меня.

Когда я запрашиваю разрешение ACCESS_FINE_LOCATION, я получаю около 100-метровой точности, отличной от GPS. Поскольку мне не нужна точность GPS, а точность городского блока, я хотел бы запросить только разрешение ACCESS_COARSE_LOCATION. Однако, когда я запрашиваю разрешение ACCESS_COARSE_LOCATION, я получаю точность в 2 км. Похоже, что устройство больше не использует разрешение Wifi и только точность ячейки.

Как я могу получить лучшую точность с разрешением ACCESS_COARSE_LOCATION?

Примечание. GPS отключен на моем тестовом устройстве.

4b9b3361

Ответ 1

Это интересная проблема, и у меня создалось впечатление, что использование ACCESS_COARSE_LOCATION будет использовать Wi-Fi, так как это говорит документация.

В документации для 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 Location Service и другим приложениям сканировать для Wi-Fi сети, даже если Wi-Fi выключен.

Итак, это наверняка исказило бы результаты, если бы он был включен.

Обратите внимание, что у меня также был режим местоположения, установленный в режиме экономии батареи для всех тестов, поэтому GPS-радио было отключено все время.

Ниже приведены результаты PRIORITY_BALANCED_POWER_ACCURACY, ACCESS_COARSE_LOCATION и нет Wi-Fi:

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 в LocationRequest, сохранив android.permission.ACCESS_COARSE_LOCATION в AndroidManifest.xml.

Нет Wi-Fi:

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 метров, и вот как близко он был на карте:

enter image description here

Затем я включил Wi-Fi, и вот результат:

accuracy: 18.847 lat: 37.779679 lon: -122.3930918

Он буквально отображается, как вы можете видеть на карте:

enter image description here

Кажется, что в вашем коде LocationRequest в коде Java меньше всего используется то, что вы используете в AndroidManifest.xml, так как результаты здесь ясно показывают, что при использовании ACCESS_FINE_LOCATION, имея Wi-Fi радио включено или выключено, сделало огромную разницу в точности, и оно было также более точным в целом.

Конечно, похоже, что документация немного несовместима, и что при использовании android.permission.ACCESS_COARSE_LOCATION включение и выключение радио Wi-Fi не имеет значения, когда ваше приложение является единственным, кто делает запросы на размещение.

Еще одна вещь, о которой говорится в документации, заключается в том, что использование PRIORITY_BALANCED_POWER_ACCURACY позволит вашему приложению "копировать" на запросы местоположения, сделанные другими приложениями. Из документации:

Им будет присвоена вину за власть за интервал, установленный setInterval (long), , но все равно могут получать местоположения, инициированные другими приложений со скоростью до setFastestInterval (long).

Итак, если пользователь открывает Карты Google, в соответствии с документацией ваше приложение может получить более точное местоположение в этот момент. Это одна из главных сторон использования нового поставщика Fused Location Provider, а не более старых API, поскольку он уменьшает количество утечки батареи вашего приложения без особых усилий с вашей стороны.

Изменить: я выполнил проверку этой функции, чтобы узнать, что произойдет при использовании ACCESS_COARSE_LOCATION.

Первый тест: ACCESS_COARSE_LOCATION, PRIORITY_BALANCED_POWER_ACCURACY и WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662

Это поместило меня в воду, довольно далеко от моего текущего местоположения. Затем я вышел из тестового приложения, запустил Google Maps, который нашел меня именно там, где я есть, а затем снова запустил тестовое приложение. Тестирующее приложение не смогло переместиться на местоположение с Карт Google, и результат был таким же, как и раньше!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662

Я повторно проверил это несколько раз, просто, чтобы убедиться, но похоже, что использование ACCESS_COARSE_LOCATION также отключает способность приложений "копировать" в местоположения, полученные другими приложениями.

Похоже, что использование ACCESS_COARSE_LOCATION в AndroidManifest.xml действительно калечит приложение с точки зрения получения точных данных о местоположении.

В заключение, единственное, что вы действительно можете сделать, - это отточить лучшее сочетание настроек, которые работают для вас и вашего приложения, и, надеюсь, результаты этого теста помогут вам принять это решение.

Ответ 2

Когда вы запрашиваете разрешение ACCESS_COARSE_LOCATION, клиент с плавным местоположением даст вам точность городского блока, что предполагаемое поведение и оно написано в документации. Посмотрите здесь в разделе "Укажите разрешения приложений"
Что я могу предложить, так это то, что вы используете обычный провайдер местоположения Android (не плавное местоположение) и пытаетесь получить доступ к поставщику NETWORK. Это должно дать вам точность WIFI.