onLocationResult会触发但LocationResult为空

时间:2018-06-01 17:46:17

标签: android location google-play-services

我刚刚切换到使用新的FusedLocationProviderClient而不是旧的FusedLocationProviderApi

以下代码几乎适用于所有设备。但是,在某些三星手机上,它偶尔会做一些奇怪的事情:Google Play服务会调用onLocationResult,但不提供LocationResult个对象。据我了解文档,这应该不会发生,因为onLocationResult的重点是它只在有位置更新时触发,为什么我会获得null个位置?为什么只在某些设备上?

public class ButtonActivity extends AppCompatActivity {

    // ...

    // An instance of my listener inner class
    private LocationProcessor locationProcessor;

    private FusedLocationProviderClient fusedLocationClient;


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

        // ...

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        locationProcessor = new LocationProcessor();

    }

    @Override
    protected void onResume() {
        // ...

        locationProcessor.enable();

        super.onResume();
    }

    private class LocationProcessor extends LocationCallback {
        // SettableBoolean is something simple we wrote to be able to synchronize on a boolean
        private final SettableBoolean isEnabled = new SettableBoolean(false);

        private void disable() {
            if (fusedLocationClient != null) {
                fusedLocationClient.removeLocationUpdates(this);
            }

            synchronized (isEnabled) {
                isEnabled.setBoolean(false);
            }
        }

        private void enable() {
            if (ActivityCompat.checkSelfPermission(ButtonActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(ButtonActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(ButtonActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_FINE_LOCATION);
                return;
            }

            synchronized (isEnabled) {
                if (isEnabled.getBoolean()) {
                    return;
                }
                isEnabled.setBoolean(true);
            }

            // Check if we already know about a location before we start listening for updates.
            Task<Location> locationTask = fusedLocationClient.getLastLocation();
            Location lastLocation = locationTask.isSuccessful() ? locationTask.getResult() : null;
            if (lastLocation != null) {
                long locationAcceptableAge_s = (long) getResources().getInteger(R.integer.location_acceptable_age_s);
                long locationAge = locationAgeInSeconds(lastLocation);
                if (locationAge <= locationAcceptableAge_s) {
                    User.setCurrentLocation(lastLocation);
                }
            } else {
                Log.w(TAG, "no location at onConnected");
            }

            long locationInterval_ms = (long) getResources().getInteger(R.integer.location_interval_active_ms);
            long fastestLocationInterval_ms = (long) getResources().getInteger(R.integer.fastest_location_interval_ms);
            int locationResolution = getResources().getInteger(R.integer.location_resolution_m);

            LocationRequest locationRequest = LocationRequest.create()
                .setInterval(locationInterval_ms)
                .setFastestInterval(fastestLocationInterval_ms)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setSmallestDisplacement(locationResolution);

            fusedLocationClient.requestLocationUpdates(locationRequest, this, null);
        }

        @Override
        public void onLocationResult(LocationResult locationResult) {
            // The only place this is ever a problem is on some Samsung devices. Everyone else ALWAYS has
            // a `lastLocation` to be gotten.
            if (locationResult == null) {
                Log.d(TAG, "onLocationChanged: NO LOCATION FOUND");
                // This displays a dialog to the user that we cannot determine their location
                resetInterface(getString(R.string.no_location_api));
                return;
            }

            Location location = locationResult.getLastLocation();
            Log.d(TAG, "onLocationChanged: " + location.getProvider());
            User.setCurrentLocation(location);
        }

        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            if (locationAvailability.isLocationAvailable()) {
                enable();
            } else {
                String noLocationAPI = getString(R.string.no_location_api);
                resetInterface(noLocationAPI);
            }
        }
    }

}

0 个答案:

没有答案