Android FusedLocationClient не запрашивает новые образцы

Как заставить FusedLocationProviderClient явно запрашивать новое местоположение?

Несколько месяцев назад я обновил FusedLocationProviderClient. С тех пор запрос на пробу нового местоположения не дает нового.

// Request a single location. 
//   Note: FusedLocationProviderClient.lastLocation
//   is no better
val request = LocationRequest()
                .setNumUpdates(1)
                .setExpirationDuration(0)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setMaxWaitTime(10*DateUtils.SECOND_IN_MILLIS)
                .setFastestInterval(0)
        fusedLocationClient?.requestLocationUpdates(request, object:LocationCallback() {
            override fun onLocationResult(result: LocationResult?) {
                super.onLocationResult(result)
                Log.v(LOG_TAG, "Single fused location request yields ${result?.lastLocation} ")
                callOnDone(result?.lastLocation)
            }
        }, Looper.getMainLooper())

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

Я использую эмулятор с записью моего трека в формате GPX, поэтому показания GPS всегда доступны.

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

(context?.getSystemService(Context.LOCATION_SERVICE) as? LocationManager)?
   .requestSingleUpdate(
       LocationManager.GPS_PROVIDER, 
       object :LocationListener{...dummy, just log the callback...},
       Looper.getMainLooper())

Вывод: FusedLocationProviderClient не будет запрашивать новые расположения у ОС даже в режиме высокого приоритета. Однако он принимает новые местоположения, если они доступны извне.

Возникает вопрос: как заставить FusedLocationProviderClient упреждающе запрашивать новое местоположение, когда оно мне нужно здесь и сейчас?


person Maneki Neko    schedule 26.03.2018    source источник


Ответы (1)


Этот вопрос довольно старый, но я пришел сюда с аналогичным вопросом, и я вижу, что за последние пару месяцев появилось около 65 других. Следующий код работает. Он передает Location обратному вызову onLocationResult в locationResult.getLastLocation():

   public void getNewLocation() {
  LocationRequest locationRequest = new LocationRequest()
        .setNumUpdates(1)
        .setFastestInterval(0)
        .setSmallestDisplacement(0)
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  if (ActivityCompat.checkSelfPermission(context,
        Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
        && ActivityCompat.checkSelfPermission(context,
        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
     return;
  }
  fusedLocationProviderClient.requestLocationUpdates(locationRequest,
              new com.google.android.gms.location.LocationCallback() {
                 @Override
                 public void onLocationResult(LocationResult locationResult) {
                    locationListener.onLocationChanged(locationResult.getLastLocation());
                 }
              },
        Looper.getMainLooper());

}

Разница здесь в том, что я удалил setMaxWaitTime и setExpirationDuration. Очевидно, они прерывают вызов. Если я правильно интерпретирую setExpirationDuration, это означает, что этот запрос должен истечь через x миллисекунд. Установка нуля означает, что срок действия запроса истекает немедленно, поэтому, когда местоположение становится доступным, срок действия запроса уже истек. Следовательно, нет обратного вызова onLocationChanged.

Я надеюсь, что это поможет кому-то.

person BinCodinLong    schedule 01.12.2018
comment
Неа. Это не так. И это понятно: это подмножество вышеперечисленного, представляющее собой просто фрагмент из документа Google, который просто не будет работать. - person Maneki Neko; 02.12.2018
comment
О привет; так что вы все еще смотрите этот вопрос! Это действительно подмножество исходного кода. Кажется, что setExpirationDuration и/или setMaxWaitTime вызывают сбой исходного кода. Без них это работает - для меня. - person BinCodinLong; 04.12.2018
comment
Пробовал с и без, потому что я предположил, что он не будет беспокоиться о местоположении, если время все равно истекло (хотя я все равно получил бы его и кэшировал для следующего раза). Я действительно не жду ответа, я просто надеюсь, что какой-нибудь чудесный серебряный ответ случайно спасет положение. На самом деле, я частично смягчил это хорошим насилием: запросом местоположения из Android API. В некоторых случаях это работает. - person Maneki Neko; 04.12.2018
comment
Я просто добавил некоторые пояснения к своему ответу. Еще одно отличие: я не использую эмулятор; Тестирую на разных реальных устройствах: OnePlus, Samsung S5, S9 и т.д. - person BinCodinLong; 04.12.2018
comment
Прохладно. Тестирую с некоторыми Xiaomi и бюджетники, и с S7. Также с OnePlus - person Maneki Neko; 04.12.2018