如果设备没有移动并且移动了 300m 的距离,则停止位置更新,然后获取它的位置

Posted

技术标签:

【中文标题】如果设备没有移动并且移动了 300m 的距离,则停止位置更新,然后获取它的位置【英文标题】:Stop location updates if the device has not moved and if it moves a distance of 300m then get it's location 【发布时间】:2017-08-16 11:39:58 【问题描述】:

我正在制作一个安卓应用程序。如果设备静止并且移动了 300 或 400m 的距离,我想停止位置更新,然后再次获取它的位置。我不想连续检查位置更新并测量先前位置和当前位置之间的距离,因为它会消耗电池。 我的位置服务类代码:

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 以最少的电池消耗实现这一目标的最佳方法是什么?

【问题讨论】:

【参考方案1】:

这里有几点需要注意:

    当您的设备不移动时,定位服务会针对电池进行优化,而不必进行昂贵的新位置查找。因此,您实际上不必尝试自己对此进行优化。 考虑将较小的值传递给LocationRequest#setSmallestDisplacement。 要针对电池进行优化,请考虑使用批量位置更新,其中以LocationRequest#setInterval 中描述的时间间隔为您计算位置,但根据LocationRequest#setMaxWaitTime 中的值传送到您的设备。这对电池很有帮助。

不是您的问题的一部分,但我应该注意,我会以稍微不同的方式构建用于请求和删除位置更新的代码。我会在onStart() 中连接GoogleApiClient,并在onStop() 中断开它。我会在onResume()onConnected() 中调用requestLocationUpdates(),在onPause()onStop() 中调用removeLocationUpdates(),但不会晚于onDestroy()

【讨论】:

以上是关于如果设备没有移动并且移动了 300m 的距离,则停止位置更新,然后获取它的位置的主要内容,如果未能解决你的问题,请参考以下文章

Javascript(Ionic)中两个移动设备之间的距离

移动距离

移动距离(15 分)

按下后退按钮时,自动折叠移动设备上的下拉导航栏菜单

蓝桥杯-移动距离

在wordpress革命滑块上将导航箭头放在移动设备上