如何在getAccuracy()低于100时停止处理程序

时间:2017-05-23 19:12:27

标签: android google-maps google-maps-android-api-2 handler

您好我正在创建一个能够获取用户位置的Android地图应用程序,但是当用户打开他们的地图时,有时位置不准确并且会慢慢找到您的位置。

我试过这个。但它仍然称处理程序和TOASTS不会停止。

default_

我添加了一个每5秒运行一次的处理程序来检查用户位置,当getAccuracy数据等于或小于100时,它将停止。我该怎么做?

2 个答案:

答案 0 :(得分:3)

getCurrentLocation可以调用handler.removeCallbacks(runnable);,但是runnable将始终调用handler.postDelayed(this, 3000);

要解决这个问题,必须要有一些条件让Runnable检查它是否应该再次发布。

解决方案是让getCurrentLocation返回一个布尔值,指示它是否成功(足够):

private boolean getCurrentLocation() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return false;
    }
    Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    if (location != null) {
        longitude = location.getLongitude();
        latitude = location.getLatitude();

        moveMap();

        Integer loc = Math.round(location.getAccuracy());
        textings.setText(Integer.toString(loc));

        if(loc <= 100) {
            handler.removeCallbacks(runnable);
            Toast.makeText(mapsPage.this, "HANDLER STOPPED", Toast.LENGTH_SHORT).show();
            return true;
        }
    }
    return false;
}

然后在Runnable检查中是否需要另一次运行:

@Override
public void run() {
    if(!getCurrentLocation()) {
        handler.postDelayed(this, 3000);
    }
}

然而,所有这些,您应该只检查LocationListener的onLocationChanged中的位置,并在该位置足够准确时执行某些操作。那么你根本不需要Runnable。

答案 1 :(得分:2)

你绝对应该接受RobCo的答案作为正确的答案,因为它直接解决你的问题,并提供额外的关键洞察力(即你根本不需要Runnable)。

但是,我很好奇RobCo的方法是什么样的,所以我创建了一个可能的实现方法。

事实证明,如果我们避开Runnable并依赖Google的回调,我们就可以使用更新的位置提供程序API(LocatonServices.FusedLocationApi)。可以消除旧的LocationManager API。

因此,在此实现中,我让Google位置服务在位置发生变化时触发回调(而不是使用来自客户端的定期民意调查):

public class MainActivity extends AppCompatActivity implements
        ActivityCompat.OnRequestPermissionsResultCallback, GoogleApiClient.OnConnectionFailedListener,
        GoogleApiClient.ConnectionCallbacks,
        com.google.android.gms.location.LocationListener {

    private static final String TAG = MainActivity.class.getSimpleName();

    private static final int PERMISSION_REQUEST_CODE = 10001;
    public static final int LOCATION_UPDATE_INTERVAL = 5000; // milliseconds
    private GoogleApiClient googleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        googleApiClient = new GoogleApiClient.Builder(this, this, this)
                .enableAutoManage(this, this)
                .addApi(LocationServices.API)
                .build();

        googleApiClient.connect();
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(this,
                new String[]{ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
    }

    private void initLocationServices() {
        try {
            // make initial, synchronous request for current location
            Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
            if (location != null) {
                moveMap(location);
            }

            // request future location updates which will come in as callbacks later, when available
            LocationRequest locationRequest = new LocationRequest();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(LOCATION_UPDATE_INTERVAL);
            LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
        } catch (SecurityException se) {
            Log.w(TAG, "App does not have sufficient permission to request location. " +
                    "Requesting permission now...");
            requestPermission();
        }
    }

    private void moveMap(Location location) {
        Log.v(TAG, "moveMap");

        // TODO: actual map moving code goes here
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.e(TAG, "Connection failed:" + connectionResult.getErrorMessage());
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE && grantResults[0] == PERMISSION_GRANTED && grantResults[1] == PERMISSION_GRANTED) {
            Log.v(TAG, "User granted permission. Will request current location.");
            initLocationServices();
        } else {
            Log.w(TAG, "User did not grant permission. Cannot request location. Cannot proceed.");
        }
    }

    @Override
    public void onLocationChanged(Location newLocation) {
        Log.v(TAG, "onLocationChanged:" + newLocation.toString());
        moveMap(newLocation);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if ((ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED)
                && (ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED)) {
            initLocationServices();
        } else {
            Log.w(TAG, "onCreate: requesting sufficient permission from user");
            requestPermission();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.v(TAG, "onConnectionSuspended");
    }
}

这个特定实现的缺点是MainActivity实现了几个接口并且增加了一些混淆(这些方法在这里做了什么?等等)

说不上。也许它很有用。无论如何,祝你的应用好运。