What is the difference between these two ways of getting the users location?

二次信任 提交于 2021-02-08 11:21:28

问题


From what I understand this is a way of getting the users location and displaying a blue circle on the google map.

/**
 * Enables the My Location layer if the fine location permission has been granted.
 */
private void enableMyLocation() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission to access the location is missing.
        PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
                Manifest.permission.ACCESS_FINE_LOCATION, true);
    } else if (mMap != null) {
        // Access to the location has been granted to the app.
        mMap.setMyLocationEnabled(true);
    }
}

What does the line mMap.setMyLocationEnabled(true); actually do? Can I get the users lat and long values from this method.

There is another method that seems to work too. It uses the fused location provider.

public class LocationProvider implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    public interface LocationCallback {
        void handleNewLocation(Location location);
    }

    public static final String TAG = LocationProvider.class.getSimpleName();

    /*
     * Define a request code to send to Google Play services
     * This code is returned in Activity.onActivityResult
     */
    private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
    private static final int LOCATION_INTERVAL = 5000;
    private static final int LOCATION_FAST_INTERVAL = 1000;

    private LocationCallback mLocationCallback;
    private Context mContext;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    public LocationProvider(Context context) {
        mGoogleApiClient = new GoogleApiClient.Builder(context)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(LOCATION_INTERVAL)        // 5 seconds, in milliseconds
                .setFastestInterval(LOCATION_FAST_INTERVAL); // 1 second, in milliseconds
        if (context instanceof LocationCallback) mLocationCallback = (LocationCallback) context;
        mContext = context;
    }

    public void connect() {
            mGoogleApiClient.connect();
    }

    public void disconnect() {
        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.i(TAG, "Location services connected.");

        if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, 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;
        }

        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
        else {
            mLocationCallback.handleNewLocation(location);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        /*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution() && mContext instanceof Activity) {
            try {
                Activity activity = (Activity) mContext;
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
            /*
             * Thrown if Google Play services canceled the original
             * PendingIntent
             */
            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
            /*
             * If no resolution is available, display a dialog to the
             * user with the error.
             */
            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        mLocationCallback.handleNewLocation(location);
    }
}

My maps activity overrides the method handleNewLocation(Location location) and displays a marker on the google map for the user's location.

Which method is the best way and what does the first method actually do. Do both need to be used?


回答1:


Both methods do NOT need to be used; they are redundant.

I'm assuming you've read the setMyLocationEnabled() docs, so you may be wondering if it's the best/most direct way to get the device's location. It is not, in the sense that it requires a MapView to be present. What if you don't want to be showing your user a MapView? The GoogleMap starts multiple background threads/internet connections (in order to cache map tiles and so forth), and this is a lot of extra work to do if you just want to snag the coordinates of that little blue circle. Which you could do, by the way, using the deprecated setOnMyLocationChangeListener() method, in a fashion similar to your second example.

setMyLocationEnabled() tells the GoogleMap to set up a location provider behind the scenes. That's basically what your second example is; a way to get a steady stream of Locations -- from the Fused Location API, in this case. Then you pass that information to the marker on the GoogleMap, which is, of course, pretty much the same thing you accomplished in example 1 by calling setMyLocationEnabled().

If you just want to know what your GPS coordinates are, I find the GPS_PROVIDER much more direct:

LocationManager lm = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
lm.requestLocationUpdates( LocationManager.GPS_PROVIDER, 100, 0.0f, this, null );

That way, you don't have to tell Google where you are, just so they can tell you where you are...



来源:https://stackoverflow.com/questions/39184521/what-is-the-difference-between-these-two-ways-of-getting-the-users-location

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!