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

Продвинутое поведение провайдера Fused Location

так я регистрирую свое приложение для получения обновлений местоположения:

mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(Consts.ONE_MINUTE * 10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setFastestInterval(Consts.ONE_MINUTE);

Builder builder = new GoogleApiClient.Builder(context);
builder.addApi(ActivityRecognition.API);

mGoogleApiClient = builder.addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

mGoogleApiClient.connect();

....
....

@Override
public void onConnected(Bundle connectionHint) {
   LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationUpdatespendingInent);
}

мое ожидающее намерение было вызвано в фоновом режиме почти точными запрошенными интервалами...

пока что так хорошо.

проблема: Когда WIFI отключен/не подключен к какой-либо сети или когда нет сетевых данных 3G/4G, - поставщик плавного доступа не предоставляет новые обновления местоположения!

Мои настройки доступа к местоположению включены, а GPS-спутники и WI-FI и местоположение мобильной сети проверены.

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

в соответствии с документацией PRIORITY_BALANCED_POWER_ACCURACY:

Используется с setPriority (int) для запроса точности "блока". Точность уровня блока считается равной 100-метровой точности. Использование грубой точности, такой как это, часто потребляет меньше энергии.

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

другая непредсказуемая и тревожная проблема:

Я изменил PRIORITY_BALANCED_POWER_ACCURACY на PRIORITY_HIGH_ACCURACY, чтобы увидеть, как он себя ведет (в течение 24 часов). все интервалы остались прежними (интервал между обновлениями - 10 минут). точное местоположение действительно получено даже в телефонах без сети/сим-карты, но - аккумулятор разрядился быстро! когда я смотрел историю батареи, я был удивлен, увидев, что радиостанция GPS была в режиме полной передачи все время!!!!, и я видел также в своем журнале, что loction принималась каждую минуту, даже что я запросил местоположение каждые десять минут (у меня нет каких-либо других установленных приложений, которые открывают GPS для получения мест.)

Я заметил это поведение на нескольких устройствах (таких как Moto X 2013, HTC One X, Nexus 5), все с последними сервисами Google Play (версия 6.1.11) и android KITKAT 4.4.4

мое приложение сильно зависит от текущего местоположения пользователя и периодически получает обновления местоположения в указанном интервале до тех пор, пока пользователь вошел в систему, поэтому я не хочу использовать режим PRIORITY_HIGH_ACCURACY, чтобы предотвратить утечку аккумулятора..

мои вопросы:

  • Предполагается, что провайдер с плавным местоположением вообще использует GPS, если он настроен на получение обновлений с помощью PRIORITY_BALANCED_POWER_ACCURACY и не имеет информации о WI-FI или ячейках.

  • если это так, то что я делаю неправильно?

  • Почему я ошибаюсь в том, что это неверные данные об ошибках? (как я объяснил в разделе "еще большая проблема".

  • почему GPS-радио все время открыто, а не открыто в течение 10-минутного интервала, когда я использовал параметр PRIORITY_HIGH_ACCURACY? (У меня нет других установленных приложений, которые быстрее ускоряют обновление местоположения.)

4b9b3361

Ответ 1

По указанным вопросам

1. является провайдером с плавным определением местоположения, предположительно вообще использующим GPS, если он настроен на получение обновлений с помощью PRIORITY_BALANCED_POWER_ACCURACY и не имеет информации о WI-FI или ячейках. &
2., если это так, то что я делаю неправильно?

По-видимому, нигде в документации не указывается однозначно уникальный источник. С помощью опций PRIORITY, даже через код, "источник" полученного location "слит".
[location.getProvider() возвращает: "fused" ]
Я видел, что GPS используется только тогда, когда LocationRequest имеет PRIORITY_HIGH_ACCURACY. Таким образом, он не использует GPS в других условиях.

4. почему GPS-радио открыто все время, а не открыто в течение 10-минутного интервала, когда я использовал параметр PRIORITY_HIGH_ACCURACY? (У меня нет других установленных приложений, которые быстрее ускоряют обновление местоположения.)

Самый быстрый интервал установлен на 1 минуту. Из того, что я понял, setFastestInterval имеет приоритет над setInterval, когда значение для самого быстрого интервала короче по длительности, чем значение setInterval.
В вашем случае, 1 минута против 10.
Об отсутствии других установленных приложений, которые запускают обновления местоположения, только что приведенные в качестве примера и не указали, что только этот случай явно.

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

Итак, что происходит с PRIORITY_HIGH_ACCURACY, он запрашивает location в самом быстром интервале - 1min, используя GPS (только для исключительного).

3. Почему я ошибаюсь в том, что эти неправильные данные об ошибках? (как я объяснил в разделе "еще большая проблема".

Необходимо также проверить код для механизма pendingIntent. Хотя может быть несколько вещей, чтобы принять к сведению:
Вы можете добавить location.getTime(), чтобы обеспечить и проверить время получения местоположения. Скорее всего, он не обновляется, если в радиусе нет башни с Wi-Fi-ячейками и используется PRIORITY_BALANCED_POWER_ACCURACY.
Точность местоположения блока на первом месте, которая используется при вызове "lastKnown", не помогла бы.

Потребление батареи было связано с комбинацией GPS и 1-минутным обновлением. Попробуйте установить самый быстрый интервал как 5 или 10 минут, если это подходит для вашей реализации, но PRIORITY_BALANCED_POWER может не помочь, если вам нужно абсолютно точное местоположение. Обычно я добавляю чек для местоположения, полученного в onLocationChanged, и в зависимости от этого переключите приоритет в LocationRequest. Это помогает, конечно, получить местоположение вообще, если я не вхожу в здание, не имеющее прямой видимости для GPS и Wi-Fi-сети.

Ответ 2

Я предлагаю вам использовать AlarmManager и FusedLocationProvider вместе таким образом, чтобы ваша тревога AlarmManager срабатывала каждые 10 минут с целью запуска обновлений местоположения.

Как только вы получите обновленное местоположение, отключите клиента местоположения. Вам не нужно постоянно его запускать, установив интервал времени в LocationRequest, вместо этого вы можете вызвать процесс на каждом временном интервале с помощью AlarmManager.

В таком виде вы получите следующие преимущества, которые помогут решить ваши проблемы:

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

Я надеюсь, что это будет полезно.

Ответ 3

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

@Override
public void onLocationChanged(Location location) {
    //it happens
    if (location == null) {
        return;
    }
    // all locations should have an accuracy
    if (!location.hasAccuracy()) {
        return;
    }
    // if its not accurate enough don't use it
    // this value is in meters
    if (location.getAccuracy() > 200) {
        return;
    }
}

Вы можете поместить трансляцию сети в состояние сети, а когда нет соединения, вы можете перезапустить своего провайдера местоположения с помощью priority_high_accuracy, который будет использовать GPS только в том случае, если у пользователя включен GPS, иначе он падает на антенны Wi-Fi и сотовые.

<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

/** Checks whether the device currently has a network connection */

private boolean isDeviceOnline() {
    ConnectivityManager connMgr = (ConnectivityManager) activity
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        return true;
    }
    return false;
}

Ответ 4

Для обновления координат GPS вы также можете использовать провайдеры GPS и WI-FI. Для обновления позиции используйте также минимальный параметр расстояния. Я дам вам небольшой пример обслуживания GPS.

Ответы:

1) PRIORITY_BALANCED_POWER_ACCURACY do not использует GPS.

2) Для определения местоположения используйте GPS и WI-FI.

3) PRIORITY_BALANCED_POWER_ACCURACY, вероятно, из-за отсутствия области WI-FI.

Пример кода:

public class GPSservice extends Service implements LocationListener {


    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 2;

    private static final long MIN_TIME_BW_UPDATES = 1000 * 1;

    double latitude, longitude;

    boolean isGPSEnabled = false;

    boolean isNetworkEnabled = false;

    boolean canGetLocation = false;

    Location location;

    protected LocationManager locationManager;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        getLocation();

        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onLocationChanged(Location location) {
        new LocationReceiver(location, getApplicationContext());
    }


    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public Location getLocation() {
        try {
            locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                Log.d("Network", "NO network");
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }
}