2016-09-15 4 views
0

Мне нужно обновить плавленое местоположение каждые 1 мин и на каждые 5 метров (я знаю его плохую практику, но ради тестирования и показа в журнале), и я запускаю сервис кнопкой. нажата кнопка Я получил местоположение в logcat, но только один раз. В соответствии с Класс обслуживанияonLocationChanged должен вызываться каждые 1 мин, но он никогда не звонит снова, даже мой GPS включается почти каждый мин, а затем выключается через некоторое время, но все еще нет обновления местоположения в Logcat.I нужен класс обслуживания для сохранения обновление данных о местоположении без осуществления UI или основного потокаСлужба Android не обновляет местоположение

Вот LogCat, который показывает обновление местоположения только один раз

09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service onConnected Calling 
09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Start Location Update is Calling 
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service OnLocationChanged Calling 
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Here is Updated Locations: Latitude 28.5XXXXX Longitude 77.2XXXXX 
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Sending Location Starting Accuracy is: 37.5 

Вот мой класс службы

public class Location_Service_background extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 
    public static final String TAG = "===Location Service==="; 
    GoogleApiClient apiClient; 
    Location mCurrentLocation; 
    LocationRequest locationRequest; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     GoogleApiSetup(); 
     RequestLocationUpdates(); 
     Log.d(TAG,"OnStartCommand Is Calling "); 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO: Return the communication channel to the service. 
     throw new UnsupportedOperationException("Not yet implemented"); 
    } 



    @Override 
    public void onCreate() { 
     super.onCreate(); 

    } 


    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if (apiClient.isConnected()){ 
      Log.d(TAG,"Service On Destroy Calling and apiClient is Connected"); 
      StopLocationUpdates(); 
      apiClient.disconnect(); 
     } 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
    } 

    @Override 
    public void onConnected(@Nullable Bundle bundle) { 
     Log.d(TAG,"Service onConnected Calling"); 
     if (mCurrentLocation != null) { 
      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
       return; 
      } 
      mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient); 

     } 
     else { 
      Log.d(TAG,"Start Location Update is Calling"); 
      StartLocationUpdate(); 
     } 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.d(TAG,"Service OnConnectionSuspended Calling"); 
     apiClient.connect(); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.d(TAG,"Service OnLocationChanged Calling"); 
     mCurrentLocation=location; 
     Log.d(TAG,"Here is Updated Locations: Latitude "+mCurrentLocation.getLatitude()+"Longitude "+mCurrentLocation.getLongitude()); 
     String Latitude= String.valueOf(mCurrentLocation.getLatitude()); 
     String Longitude=String.valueOf(mCurrentLocation.getLongitude()); 
     String Accuracy=String.valueOf(mCurrentLocation.getAccuracy()); 
     Log.d(TAG,"Sending Location Starting"+" "+" Accuracy is: "+mCurrentLocation.getAccuracy()); 


    } 

    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
     Log.d(TAG,"Connection Failed Called "+connectionResult); 
    } 



    private synchronized void GoogleApiSetup() { 
     apiClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .build(); 
     apiClient.connect(); 
    } 

    private void RequestLocationUpdates() { 
     locationRequest = new LocationRequest(); 
     //1 Min = 60 seconds AND 1000 milliseconds in 1 second 
     locationRequest.setInterval(60 * 1000);//5 Min 300 x 1000=300000 
     locationRequest.setFastestInterval(60 * 1000);//2 Min 
     locationRequest.setSmallestDisplacement(5); 
     locationRequest.setMaxWaitTime(60*1000); 
     locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    } 

    private void StopLocationUpdates() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this); 
    } 

    private void StartLocationUpdate() { 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 

      return; 
     } 
     if (apiClient.isConnected()) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this); 
     } 
     else { 
      Log.d(TAG,"GoogleApiClient is not connected yet.Please Try Again"); 
      apiClient.connect(); 
     } 
    } 


} 
+0

Попробуйте это без использования setmallestdisplacement и посмотрите, что получится –

+0

Он показывает вызовы, делающие 'onLocationUpdate' без' setsmallestdisplacement', но как я могу использовать регулярное обновление с помощью setmallestdisplacement. Спасибо за помощь – androidXP

ответ

0

Предположив, что вы на самом деле перемещение устройства более чем на 5 метров между ожидаемыми обновлениями, я думаю, что может быть проблема с классом LocationRequest где метод setSmallestDisplacement() просто не работает должным образом .. или, по крайней мере, он не работает должным образом. (Я видел эти проблемы на other posts).

Вы всегда можете проверить расстояние самостоятельно, удалив setSmallestDisplacement(), и вместо того, чтобы делать:

onLocationChanged(){ 

double distance = // [ calculate distance between current lat/long and previous lat/long ] 

if (distance > 5 meters) { 

// do your normal onLocationChanged() code here 

} 

} 

Существует также Possiblity, что по какой-то причине, FusedLocationProvider не в состоянии получить доступ к GPS и вместо этого используется Wi-Fi или ячеистая башня ... в этом случае 5 м слишком мало, чтобы указать. Ваши журналы говорят, что точность составляет 37,5 метров, так что это не кажется достаточно точным, чтобы измерить 5 метров. Итак ... может быть, у вас нет разрешения на доступ к FINE в вашем манифесте?

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

+0

Я проверяю его в помещении, поэтому точность такая высокая, и у меня есть точное разрешение на размещение, поэтому GPS включен, грубое местоположение не имеет доступа к GPS. Если я установил обновление своего местоположения на 5 метров, это не должно останавливайте обновление местоположения каждые 1 минуту. Как обновление места обновления каждые 1 мин или каждые 5 метров. Если 5 метров не пересекаются, необходимо обновлять каждые 1 мин, но не обновлять его, когда я использую 'setsmallestdisplacement' и как вы предлагаете рассчитать расстояние между двумя точками его невозможно – androidXP

+0

В реальных условиях мне нужно установить интервал длительностью 10 минут или 15 минут, и что, если пользователь переместит несколько миль за этот период времени, я потеряю место, в котором он путешествовал между этими периодами времени, поэтому мне нужно придерживаться метода API для отправки местоположения после этого x метров – androidXP

+0

К сожалению, я не понял, что вы понимаете, как работает метод setdisplacement. По моему мнению, метод означает: «Только огонь метод onLocationChanged, если пользователь проехал не менее X метров, поскольку предыдущее время было уволено. Это НЕ означает: огонь каждые 5 метров, потому что это потребует от телефона постоянного мониторинга/калькуляции местоположения, чего вы пытаетесь избежать, чтобы сэкономить аккумулятор, создав интервал. –

2

Надеюсь, это поможет спасти кого-то от разочарования, которое я пережил по этой проблеме. Я использую FusedLocationAPI для запроса обновлений местоположения и GoogleApiClient. Я также делаю это из Сервиса.

Вы не получаете никаких обновлений местоположения на ваш временной интервал, потому что setSmallestDisplacement() принимает абсолютный приоритет над другими параметрами. Так что даже если у вас есть

locationRequestTimeInterval = LocationRequest.create() 
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
    .setInterval(1)  
    .setFastestInterval(1)  
    .setMaxWaitTime(1)  
    .setSmallestDisplacement(5); 

это НИКОГДА не будет срабатывать до тех пор, пока не будет выполнен минимальный параметр замены.

Решение этого вопроса состоит в том, чтобы создать два отдельных параметра LocationRequests ... которые касаются только расстояния, а другое - только время и использование одного GoogleApiClient для создания двух команд requestLocationUpdates, использующих Time LocationRequest, а другой - с помощью Distance LocationRequest.

Так что ваши 2 LocationRequests выглядеть следующим образом:

locationRequestDistanceInterval = LocationRequest.create() 
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
      .setFastestInterval(0) // This MUST be set, otherwise no updates 
      .setSmallestDisplacement(LOCATION_REQUEST_MIN_DISTNACE); 

locationRequestTimeInterval = LocationRequest.create() 
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
      .setInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL) 
      .setFastestInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL); 
  • отмечает, что значение setFastestInterval() должно быть установлено на запросе расстояния, в противном случае запрос на расстоянии не будет срабатывать.Это не должно быть 0, но это поле должно быть установлено.

Затем в ваших GoogleApiClients onConnected() вы можете добавить два вызова requestLocationUpdates().

LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, locationRequestDistanceInterval, new LocationListener() { 
     @Override 
     public void onLocationChanged(Location location) { 
      // Handle your Distance based updates 
     }); 
    LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, locationRequestTimeInterval, new LocationListener() { 
     @Override 
     public void onLocationChanged(Location location) { 
      // Handle your Time based updates 
     } 
    }); 

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

Смежные вопросы