Остановить обновление местоположения, если устройство не двигалось, и если оно перемещается на расстояние 300 м, получить его местоположение

Я делаю приложение для Android. Я хочу остановить обновления местоположения, если устройство неподвижно, и если оно перемещается на расстояние 300 или 400 м, а затем снова получить его местоположение. Я не хочу постоянно проверять обновления местоположения и измерять расстояние между предыдущим местоположением и текущим местоположением, потому что это потребляет заряд батареи. Код класса службы «Мое местоположение»:

public class LocationService extends Service implements
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }
}

@Override
public void onCreate() {
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

public void buildGoogleApiClient() {
    createLocationRequest();
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }
}

protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(500);
}

public void startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
    mGoogleApiClient.disconnect();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    buildGoogleApiClient();
    return START_STICKY;
}

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

@Override
public void onDestroy() {
    // The service is no longer used and is being destroyed
    stopLocationUpdates();
}

@Override
public void onLocationChanged(Location location) {
    System.out.println("Latitude: " + location.getLatitude());
    System.out.println("Longitude: " + location.getLongitude());
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

Я использую locationRequest.setSmallestDisplacement(500), но он постоянно получает обновления местоположения, только метод onLocationChanged не вызывается, если расстояние между предыдущим и текущим местоположением меньше 500 м, например.

Должен ли я использовать геозону для этой цели? Каков наилучший способ добиться этого с помощью FusedLocationApi с минимальным потреблением заряда батареи?


person Linux Holic    schedule 23.03.2017    source источник


Ответы (1)


Здесь следует отметить несколько вещей:

  1. Когда ваше устройство не движется, службы определения местоположения оптимизируют расход заряда батареи и не обязательно выполняют дорогостоящие поиски новых местоположений. Таким образом, вам не нужно пытаться оптимизировать это самостоятельно.
  2. Рассмотрите возможность передачи меньшего значения в LocationRequest#setSmallestDisplacement.
  3. Чтобы оптимизировать расход заряда батареи, рассмотрите возможность использования пакетных обновлений местоположения, когда ваше местоположение вычисляется с интервалом, описанным в LocationRequest#setInterval, но доставляется на ваше устройство на основе значения в LocationRequest#setMaxWaitTime. Это очень помогает с батареей.

Не является частью вашего вопроса, но я должен отметить, что я бы структурировал код для запроса и удаления обновлений местоположения немного по-другому. Я бы подключил GoogleApiClient к onStart() и отключил его к onStop(). Я бы позвонил requestLocationUpdates() в onResume() или в onConnected() и позвонил бы removeLocationUpdates() в onPause() или onStop(), но не позднее onDestroy().

person Shailen Tuli    schedule 24.03.2017