Android 如果设备未移动,停止位置更新,如果移动300米,则获取它';s位置

Android 如果设备未移动,停止位置更新,如果移动300米,则获取它';s位置,android,geolocation,location,fusedlocationproviderapi,android-fusedlocation,Android,Geolocation,Location,Fusedlocationproviderapi,Android Fusedlocation,我正在制作一个android应用程序。我想停止位置更新,如果设备仍然是,如果它移动了300或400米的距离,然后再次获得它的位置。我不想连续检查位置更新,也不想测量前一个位置和当前位置之间的距离,因为它会消耗电池。 我的位置服务类别代码: public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFaile

我正在制作一个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),但它会持续接收位置更新。如果上一个位置和当前位置之间的距离小于500米,则不会调用onLocationChanged方法,例如

我应该为此使用地理围栏吗?
使用FusedLocationApi以最小的电池消耗实现这一目标的最佳方法是什么?

这里有几点需要注意:

  • 当您的设备不移动时,位置服务会优化电池,而不必进行昂贵的新位置查找。所以,你真的不必亲自尝试优化
  • 考虑将较小的值传递给
    LocationRequest#setSmallestDisplacement
  • 为了优化电池,考虑使用批处理位置更新,其中在计算的时间间隔中为您计算位置,但是根据值在您的设备中传递。这对电池有很大帮助
  • 这不是你问题的一部分,但我应该注意到,我将以稍微不同的方式构建请求和删除位置更新的代码。我将在
    onStart()
    中连接
    GoogleAppClient
    ,然后在
    onStop()中断开它的连接。我会在
    onConnected()
    onResume()
    中调用
    requestLocationUpdates()
    ,在
    onPause()
    onStop()
    中调用
    removeLocationUpdates()
    ,但不会比
    onDestroy()