Неожиданное поведение Fused Location Provider

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

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-радио все время было в режиме полной передачи !!!! и я также увидел в своем журнале, что сигнал принимался каждую минуту, даже что я запрашивал местоположение каждые десять минут (у меня нет других установленных приложений, которые открывают 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? (У меня нет других установленных приложений, которые ускоряют обновление местоположения ..)


person Tal Kanel    schedule 05.10.2014    source источник


Ответы (4)


По заданным вопросам,

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

По-видимому, в документации нигде не указан явно уникальный источник. При использовании любых PRIORITY параметров, даже с помощью кода, "источник" полученного location является "объединенным".
[location.getProvider() returns: "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 на самом быстром заданном интервале - 1 мин, используя GPS (как бы исключительно).

3. почему я получаю неверные обновления местоположения, вводящие в заблуждение? (как я объяснил в разделе «Еще большая проблема» ..

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

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

person Pararth    schedule 08.10.2014
comment
благодарить. Я проверю, как себя ведут, когда я изменяю fastestInterval и все другие моменты, которые вы упомянули. если действительно так работает - с радостью верну награду ваш ответ - person Tal Kanel; 08.10.2014
comment
конечно, нет проблем, также попробуйте высокую точность без прямой видимости в независимом приложении только для определения местоположения, оно, вероятно, не вернет обновленное точное местоположение ... просто для обеспечения поведения - person Pararth; 08.10.2014
comment
Спасибо за помощь, изменение местоположения в самом быстром интервале действительно влияет на ожидающие обратные вызовы с намерениями, но - все же я вижу, что GPS-радио открыто на 100% (на основе данных о батарее в настройках). любая идея? - person Tal Kanel; 08.10.2014
comment
это может помочь, это один из лучших ответов на вопрос, почему GPS использует так много батареи, все еще нужно проверить в определенных контекстах мобильного приложения, я бы попытался попросить пользователя включить / отключить его в зависимости от того, когда ему / ей требовалось точное местоположение, это не сделало бы это обязательным, не сработает в вашем случае, я думаю (с учетом постоянного требования) - person Pararth; 08.10.2014
comment
Ваш ответ был единственным ответом, который дал мне понимание, о котором я не знал ... Спасибо! - person Tal Kanel; 13.10.2014
comment
Спасибо! Рад, что смог помочь - person Pararth; 14.10.2014
comment
Эти объяснения очень полезны для нового разработчика вроде меня. Я обнаружил, что новый интерфейс определения местоположения Fused очень хорош по сравнению с Location Manager / поставщиком GPS / поставщиком сети и т. Д. Но у меня были те же проблемы и вопросы в моем приложении Большое спасибо. - person Mario; 28.04.2015
comment
Спасибо, рада, что помогло - person Pararth; 28.04.2015
comment
@Mario: Предполагая, что вы говорите о новом интерфейсе Fused Location -Google Play сервисы 6.5 Отсутствует LocationClient -, вы все равно используете игровые сервисы, тогда это также поможет - улучшить взаимодействие с пользователем; Включение GPS без пользователя перенаправляется в LocationSettings - person Pararth; 28.04.2015
comment
Привет @ user2450263. Пожалуйста, проверьте мою проблему. Я хочу поменять приоритеты. Как я могу этого добиться - person Kunu; 26.05.2015
comment
либо вопрос был удален, либо проблема со ссылкой ... страница не найдена - person Pararth; 26.05.2015
comment
@ user2450263 проверьте это - person Kunu; 27.05.2015
comment
@Kunu, вам нужно зайти в Google и попытаться сделать больше, чем то, что у вас есть, не просто публикуйте требование :) - person Pararth; 27.05.2015
comment
@ user2450263 Я так и делаю. Потому что Google - единственный источник для этого. Но мне просто интересно, сделали вы это или нет, потому что в своем ответе вы сказали switch the priority in LocationRequest в onLocationChanged. Кстати спасибо :) - person Kunu; 27.05.2015
comment
эй, у меня есть проблема, когда устройство использует сотовые данные, и этот конструктор настроек местоположения запрашивает ВКЛЮЧЕНИЕ Wi-Fi. это не имеет значения. Итак, как отключить запрос Wi-Fi из ожидающего намерения, чтобы появиться. мне нужно только местоположение - person Hemant Shori; 03.08.2015
comment
Я думаю, что это необходимо и в некотором смысле актуально, потому что в PRIORITY_BALANCED_POWER_ACCURACY местоположение, предоставляемое GooglePlayServices, не находится в режиме только устройства или только GPS, это происходит с помощью алгоритма, который учитывает сопоставление таблицы точек Wi-Fi, доступных в диапазоне. Я не помню точных слов того, что я прочитал, но попытался передать вам суть. Таким образом, запросы на включение Wi-Fi могут находиться под внутренним управлением операционной системы. поскольку я сам видел их в некоторых условиях, когда местоположение необходимо получить в нескольких приложениях - person Pararth; 03.08.2015

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

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

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

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

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

person Mehul Joisar    schedule 10.10.2014
comment
на самом деле я думал сделать что-то подобное. это может сработать, но - это обходной путь, которого я предпочитаю избегать. - person Tal Kanel; 12.10.2014
comment
@TalKanel: AFAIK, это не обходной путь. Это альтернативный подход. вы можете продолжить свой текущий подход при разработке приложения специально для навигационных карт и т. д., которое будет отображаться на экране все время, когда пользователь его использует. Если это не приложение для навигации, то вам подойдет AlarmManager. - person Mehul Joisar; 13.10.2014
comment
Подключение каждые десять минут к сервисам Google Play (IPC) для регистрации и запроса одноразового местоположения пахнет плохим подходом. Вы так не думаете? Я могу ошибаться ... Пожалуйста, освети меня - person Tal Kanel; 13.10.2014
comment
@TalKanel: Вам следует выполнить тестовый запуск. Я предполагаю, что мой подход будет более удобным для пользователя и не будет сильно разряжать батарею, поскольку он не будет поддерживать GPS-радио в режиме 24x7. Вы наверняка увидите огромную разницу в производительности. Кроме того, если возможно, я бы настаивал, чтобы вы дали пользователю возможность изменить частоту получения местоположения. - person Mehul Joisar; 13.10.2014
comment
Я бы не стал использовать этот подход, чтобы избежать накладных расходов, связанных с AlarmManager. Разве это не было бы отдельным компонентом, когда мы уже можем задавать интервалы для получения локации? Кроме того, если мы не получим данные о местоположении (что может произойти в моменты отсутствия прямой видимости для GPS) в этом 1 вызове в течение 10 минут, в любом случае будет рекурсивный вызов для определения местоположения. Можно переключаться между BALANCED_POWER и HIGH_ACCURACY, в противном случае расход заряда батареи GPS может всегда оставаться, не уверен, действительно ли ответ на запрос включения / выключения будет эффективным / оптимальным, когда приложение работает в течение более длительного времени - person Pararth; 13.10.2014
comment
@TalKanel, в подходе Мехула Джойзара, из-за использования диспетчера тревог потребление батареи увеличивается, но это более надежно, потому что, если мы хотим иметь периодические обновления местоположения в фоновом режиме, мы можем использовать службы, но эти службы могут быть остановлены Android, поэтому единственно возможный вариант - использовать диспетчер сигналов тревоги для периодического вызова одноразовых служб. - person Mr.Q; 10.06.2016
comment
@TalKanel Я сделал то же самое, также вам не нужно регистрироваться в сервисах Google Play каждый раз, вам просто нужно выполнить однократную инициализацию и регистрацию и проверить, подключен ли google api и не является ли он нулевым, прежде чем продолжить, в противном случае сначала зарегистрируйтесь, затем продолжайте. Для Marshmallow и выше я использовал планировщик заданий, чтобы разбудить серверную службу для получения слитного местоположения, другого мудрого простого диспетчера аварийных сигналов для версий ниже. - person Jamil; 10.07.2017

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

@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;
}
person danny117    schedule 07.10.2014

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

Ответы:

1) PRIORITY_BALANCED_POWER_ACCURACY не < / a> использовать 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;
    }
}
person Oleg Gordiichuk    schedule 05.10.2014
comment
PRIORITY_BALANCED_POWER_ACCURACY не использует GPS - я не вижу в сообщении, которое вы предоставили, никаких доказательств того, что это так. человек там написал, что он только думает, что это значит. Кроме того, я знаю, что могу явно использовать LocationManager, но я хочу использовать рекомендуемые API служб определения местоположения - person Tal Kanel; 05.10.2014
comment
Проведите небольшое исследование самостоятельно, просто попробуйте использовать Wi-Fi и GPS и посмотрите результаты. - person Oleg Gordiichuk; 05.10.2014