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

Solutions Collecting From Web of "Продвинутое поведение провайдера Fused Location"

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

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

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

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

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

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

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

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

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

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

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

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

 @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; } 

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

Ответы:

1) PRIORITY_BALANCED_POWER_ACCURACY не использует 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; } }