How do I get the current GPS location programmatically in Android?

前端 未结 22 2657
梦谈多话
梦谈多话 2020-11-21 04:42

I need to get my current location using GPS programmatically. How can i achieve it?

相关标签:
22条回答
  • 2020-11-21 04:56

    There are already many answers there but I want to show latest way to get location using Google API, so new programmers can use new method:

    I have written detailed tutorial on current location in android at my blog demonuts.com You can also find full source code developed with android studio.

    First of all, put this in gradle file

     compile 'com.google.android.gms:play-services:9.0.2'
    

    then implement necessary interfaces

    public class MainActivity  extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener
    

    declare instances

      private GoogleApiClient mGoogleApiClient;
      private Location mLocation;
      private LocationManager locationManager;
      private LocationRequest mLocationRequest;
    

    put this in onCreate()

     mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    

    At last, override necessary methods

     @Override
        public void onConnected(Bundle bundle) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, 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;
            } startLocationUpdates();
            mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if(mLocation == null){
                startLocationUpdates();
            }
            if (mLocation != null) {
                double latitude = mLocation.getLatitude();
                double longitude = mLocation.getLongitude();
            } else {
                // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
            }
        }
    
        protected void startLocationUpdates() {
            // Create the location request
            mLocationRequest = LocationRequest.create()
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setInterval(UPDATE_INTERVAL)
                    .setFastestInterval(FASTEST_INTERVAL);
            // Request location updates
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, 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);
            Log.d("reque", "--->>>>");
        }
    
        @Override
        public void onConnectionSuspended(int i) {
            Log.i(TAG, "Connection Suspended");
            mGoogleApiClient.connect();
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
        }
    
        @Override
        public void onStart() {
            super.onStart();
            mGoogleApiClient.connect();
        }
    
        @Override
        public void onStop() {
            super.onStop();
            if (mGoogleApiClient.isConnected()) {
                mGoogleApiClient.disconnect();
            }
        }
        @Override
        public void onLocationChanged(Location location) {
    
        }
    

    Don't forget to start GPS in your device before running app.

    0 讨论(0)
  • 2020-11-21 04:56
    class MyLocation {
        Timer timer1;
        LocationManager lm;
        LocationResult locationResult;
        boolean gps_enabled = false;
        boolean network_enabled = false;
    
        public boolean getLocation(Context context, LocationResult result) {
            // I use LocationResult callback class to pass location value from
            // MyLocation to user code.
            locationResult = result;
            if (lm == null)
                lm = (LocationManager) context
                        .getSystemService(Context.LOCATION_SERVICE);
    
            // Exceptions will be thrown if the provider is not permitted.
            try {
                gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
            }
            catch (Exception ex) {
            }
            try {
                network_enabled = lm
                        .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            }
            catch (Exception ex) {
            }
    
            // Don't start listeners if no provider is enabled.
            if (!gps_enabled && !network_enabled)
                return false;
    
            if (gps_enabled)
                lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                        locationListenerGps);
            if (network_enabled)
                lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
                        locationListenerNetwork);
            timer1 = new Timer();
            timer1.schedule(new GetLastLocation(), 5000);
            return true;
        }
    
        LocationListener locationListenerGps = new LocationListener() {
            public void onLocationChanged(Location location) {
                timer1.cancel();
                locationResult.gotLocation(location);
                lm.removeUpdates(this);
                lm.removeUpdates(locationListenerNetwork);
            }
    
            public void onProviderDisabled(String provider) {
            }
    
            public void onProviderEnabled(String provider) {
            }
    
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }
        };
    
        LocationListener locationListenerNetwork = new LocationListener() {
            public void onLocationChanged(Location location) {
                timer1.cancel();
                locationResult.gotLocation(location);
                lm.removeUpdates(this);
                lm.removeUpdates(locationListenerGps);
            }
    
            public void onProviderDisabled(String provider) {
            }
    
            public void onProviderEnabled(String provider) {
            }
    
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }
        };
    
        class GetLastLocation extends TimerTask {
            @Override
            public void run() {
                lm.removeUpdates(locationListenerGps);
                lm.removeUpdates(locationListenerNetwork);
    
                Location net_loc = null, gps_loc = null;
                if (gps_enabled)
                    gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (network_enabled)
                    net_loc = lm
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    
                // If there are both values, use the latest one.
                if (gps_loc != null && net_loc != null) {
                    if (gps_loc.getTime() > net_loc.getTime())
                        locationResult.gotLocation(gps_loc);
                    else
                        locationResult.gotLocation(net_loc);
                    return;
                }
    
                if (gps_loc != null) {
                    locationResult.gotLocation(gps_loc);
                    return;
                }
                if (net_loc != null) {
                    locationResult.gotLocation(net_loc);
                    return;
                }
                locationResult.gotLocation(null);
            }
        }
    
        public static abstract class LocationResult {
            public abstract void gotLocation(Location location);
        }
    }
    

    I hope this will help you...

    0 讨论(0)
  • 2020-11-21 04:57

    LocationManager is a class that provides in-build methods to get last know location

    STEP 1 :Create a LocationManager Object as below

    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    STEP 2 : Add Criteria

    *Criteria is use for setting accuracy*
    
    Criteria criteria = new Criteria();
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    
    if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
    
        criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH);
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setAltitudeRequired(true);
        criteria.setBearingRequired(true);
        criteria.setSpeedRequired(true);
    
    }
    

    STEP 3 :GET Avaliable Provider

    Threre are two types of provider GPS and network

     String provider = locationManager.getBestProvider(criteria, true);
    

    STEP 4: Get Last Know Location

    Location location = locationManager.getLastKnownLocation(provider);
    

    STEP 5: Get Latitude and Longitude

    If location object is null then dont try to call below methods

    getLatitude and getLongitude is methods which returns double values

    0 讨论(0)
  • 2020-11-21 04:57

    GoogleSamples has verbose example using latest FusedLocationProviderApi. Unfortunately the most upvoted answers are out of date.

    Follow the below examples to implement Location Services using FusedLocationProviderApi

    https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates

    https://github.com/googlesamples/android-play-location/blob/master/LocationUpdates/app/src/main/java/com/google/android/gms/location/sample/locationupdates/MainActivity.java

    0 讨论(0)
  • 2020-11-21 05:00

    I have made a project from which we can get the accurate location using Google Play Services, GPS and Network providers. This project can be found here.

    Strategy in finding the best location is that first get the location from google play services if location is found then check weather it is better or not, if location found is null restart google play services and try to fetch the location from Android Location API. Register the location on change listeners and when ever the better location is found the call back returns it to the main activity.

    It is very simple to use and implement in code only two classes we need to embed i.e. LocationManagerInterface and SmartLocationManager, LocationActivity is implementing the interface and using SmartLocationManager to fetch location.

    /**
     * Created by Syed Raza Mehdi Naqvi on 8/10/2016.
     */
    public interface LocationManagerInterface {
        String TAG = LocationManagerInterface.class.getSimpleName();
    
        void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider);
    
    }
    

    here is the location manager class

    import android.Manifest;
    import android.app.Activity;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.IntentSender;
    import android.content.pm.PackageManager;
    import android.location.Location;
    import android.location.LocationManager;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AlertDialog;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesUtil;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationServices;
    
    import java.text.DateFormat;
    import java.util.Date;
    
    /**
     * Created by Syed Raza Mehdi Naqvi on 8/9/2016.
     */
    public class SmartLocationManager implements
            GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    
        private static final String TAG = SmartLocationManager.class.getSimpleName();
    
        private static final int TWO_MINUTES = 1000 * 60 * 2;
        private static final int PERMISSION_REQUEST_CODE = 1000;
        private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
    
        // default value is false but user can change it
        private String mLastLocationUpdateTime;                                                         // fetched location time
        private String locationProvider;                                                                // source of fetched location
    
        private Location mLastLocationFetched;                                                          // location fetched
        private Location mLocationFetched;                                                              // location fetched
        private Location networkLocation;
        private Location gpsLocation;
    
        private int mLocationPiority;
        private long mLocationFetchInterval;
        private long mFastestLocationFetchInterval;
    
        private Context mContext;                                                                       // application context
        private Activity mActivity;                                                                     // activity context
        private LocationRequest mLocationRequest;
        private GoogleApiClient mGoogleApiClient;
        private LocationManagerInterface mLocationManagerInterface;
    
        private android.location.LocationManager locationManager;
        private android.location.LocationListener locationListener;
    
        boolean isGPSEnabled;
        boolean isNetworkEnabled;
    
        private int mProviderType;
        public static final int NETWORK_PROVIDER = 1;
        public static final int ALL_PROVIDERS = 0;
        public static final int GPS_PROVIDER = 2;
    
    //    private final double STANDARD_LOCATION_ACCURACY = 100.0;
    //    private final double STANDARD_LOCATION_SEED_LIMIT = 6.95;
    
        public static final int LOCATION_PROVIDER_ALL_RESTICTION = 1;
        public static final int LOCATION_PROVIDER_RESTRICTION_NONE = 0;
        public static final int LOCATION_PROVIDER_GPS_ONLY_RESTICTION = 2;
        public static final int LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION = 3;
        private int mForceNetworkProviders = 0;
    
        public SmartLocationManager(Context context, Activity activity, LocationManagerInterface locationInterface, int providerType, int locationPiority, long locationFetchInterval, long fastestLocationFetchInterval, int forceNetworkProviders) {
            mContext = context;
            mActivity = activity;
            mProviderType = providerType;
    
            mLocationPiority = locationPiority;
            mForceNetworkProviders = forceNetworkProviders;
            mLocationFetchInterval = locationFetchInterval;
            mFastestLocationFetchInterval = fastestLocationFetchInterval;
    
            mLocationManagerInterface = locationInterface;
    
            initSmartLocationManager();
        }
    
    
        public void initSmartLocationManager() {
    
            // 1) ask for permission for Android 6 above to avoid crash
            // 2) check if gps is available
            // 3) get location using awesome strategy
    
            askLocationPermission();                            // for android version 6 above
            checkNetworkProviderEnable(mForceNetworkProviders);                       //
    
            if (isGooglePlayServicesAvailable())                // if googleplay services available
                initLocationObjts();                            // init obj for google play service and start fetching location
            else
                getLocationUsingAndroidAPI();                   // otherwise get location using Android API
        }
    
        private void initLocationObjts() {
            // Create the LocationRequest object
            mLocationRequest = LocationRequest.create()
                    .setPriority(mLocationPiority)
                    .setInterval(mLocationFetchInterval)                    // 10 seconds, in milliseconds
                    .setFastestInterval(mFastestLocationFetchInterval);     // 1 second, in milliseconds
    
            if (mGoogleApiClient == null) {
                mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .addApi(LocationServices.API)
                        .build();
            }
    
            startLocationFetching();                                        // connect google play services to fetch location
        }
    
        @Override
        public void onConnected(Bundle connectionHint) {
            Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            startLocationUpdates();
            if (location == null) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
                getLocationUsingAndroidAPI();
            } else {
                setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
            }
        }
    
        @Override
        public void onLocationChanged(Location location) {
            if (location == null) {
                getLastKnownLocation();
            } else {
                setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
            }
        }
    
        @Override
        public void onConnectionSuspended(int i) {
            Log.i(TAG, "Connection suspended");
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            if (connectionResult.hasResolution()) {
                try {
                    connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST); // Start an Activity that tries to resolve the error
                    getLocationUsingAndroidAPI();                                                                // try to get location using Android API locationManager
                } catch (IntentSender.SendIntentException e) {
                    e.printStackTrace();
                }
            } else {
                Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
            }
        }
    
        private void setNewLocation(Location location, Location oldLocation) {
            if (location != null) {
                mLastLocationFetched = oldLocation;
                mLocationFetched = location;
                mLastLocationUpdateTime = DateFormat.getTimeInstance().format(new Date());
                locationProvider = location.getProvider();
                mLocationManagerInterface.locationFetched(location, mLastLocationFetched, mLastLocationUpdateTime, location.getProvider());
            }
        }
    
        private void getLocationUsingAndroidAPI() {
            // Acquire a reference to the system Location Manager
            locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
    
            setLocationListner();
            captureLocation();
        }
    
        public void captureLocation() {
            if (Build.VERSION.SDK_INT >= 23 &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            try {
                if (mProviderType == SmartLocationManager.GPS_PROVIDER) {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
                } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) {
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
                } else {
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }
    
        private void setLocationListner() {
            // Define a listener that responds to location updates
            locationListener = new android.location.LocationListener() {
                public void onLocationChanged(Location location) {
                    // Called when a new location is found by the network location provider.
                    if (location == null) {
                        getLastKnownLocation();
                    } else {
                        setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
    //                    if (isLocationAccurate(location) && location.getAccuracy() < STANDARD_LOCATION_ACCURACY && location.getSpeed() < STANDARD_LOCATION_SEED_LIMIT) {// no use of this if
    //                        setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
    //                    } else {
    //                        setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
    //                    }
                    }
                }
    
                public void onStatusChanged(String provider, int status, Bundle extras) {
                }
    
                public void onProviderEnabled(String provider) {
                }
    
                public void onProviderDisabled(String provider) {
                }
            };
        }
    
        public Location getAccurateLocation() {
            if (Build.VERSION.SDK_INT >= 23 &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return null;
            }
            try {
                gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                Location newLocalGPS, newLocalNetwork;
                if (gpsLocation != null || networkLocation != null) {
                    newLocalGPS = getBetterLocation(mLocationFetched, gpsLocation);
                    newLocalNetwork = getBetterLocation(mLocationFetched, networkLocation);
                    setNewLocation(getBetterLocation(newLocalGPS, newLocalNetwork), mLocationFetched);
                }
            } catch (Exception ex) {
                Log.e(TAG, ex.getMessage());
            }
            return mLocationFetched;
        }
    
        protected void startLocationUpdates() {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    
        public void startLocationFetching() {
            mGoogleApiClient.connect();
            if (mGoogleApiClient.isConnected()) {
                startLocationUpdates();
            }
        }
    
        public void pauseLocationFetching() {
            if (mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
                mGoogleApiClient.disconnect();
            }
    
        }
    
        public void abortLocationFetching() {
            mGoogleApiClient.disconnect();
    
            // Remove the listener you previously added
            if (locationManager != null && locationListener != null) {
                if (Build.VERSION.SDK_INT >= 23 &&
                        ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                        ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                try {
                    locationManager.removeUpdates(locationListener);
                    locationManager = null;
                } catch (Exception ex) {
                    Log.e(TAG, ex.getMessage());
    
                }
            }
        }
    
        public void resetLocation() {
            mLocationFetched = null;
            mLastLocationFetched = null;
            networkLocation = null;
            gpsLocation = null;
        }
    
        //  Android M Permission check
        public void askLocationPermission() {
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    
    
                if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                        || ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                        ) {
                    if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION)
                            || ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION)) {
    
                        final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
                        builder.setMessage("Please allow all permissions in App Settings for additional functionality.")
                                .setCancelable(false)
                                .setPositiveButton("Allow", new DialogInterface.OnClickListener() {
                                    public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                                        Toast.makeText(mContext, "Welcome", Toast.LENGTH_SHORT).show();
                                    }
                                })
                                .setNegativeButton("Deny", new DialogInterface.OnClickListener() {
                                    public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                                        mActivity.finish();
                                    }
                                });
                        final AlertDialog alert = builder.create();
                        alert.show();
    
                    } else
                        ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION
                                , Manifest.permission.ACCESS_FINE_LOCATION
                        }, PERMISSION_REQUEST_CODE);
    
                }
            }
        }
    
        public void checkNetworkProviderEnable(int enforceActive) {
            locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
    
            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
            if (!isGPSEnabled && !isNetworkEnabled) {
                buildAlertMessageTurnOnLocationProviders("Your location providers seems to be disabled, please enable it", "OK", "Cancel");
            } else if (!isGPSEnabled && mForceNetworkProviders == LOCATION_PROVIDER_GPS_ONLY_RESTICTION) {
                buildAlertMessageTurnOnLocationProviders("Your GPS seems to be disabled, please enable it", "OK", "Cancel");
            } else if (!isNetworkEnabled && mForceNetworkProviders == LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION) {
                buildAlertMessageTurnOnLocationProviders("Your Network location provider seems to be disabled, please enable it", "OK", "Cancel");
            }
            // getting network status
    
            if (!isGPSEnabled && !isNetworkEnabled) {
                Toast.makeText(mContext, "Location can't be fetched!", Toast.LENGTH_SHORT).show(); // show alert
                mActivity.finish();
            }
        }
    
        private void buildAlertMessageTurnOnLocationProviders(String message, String positiveButtonText, String negativeButtonText) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
            builder.setMessage(message)
                    .setCancelable(false)
                    .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() {
                        public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                            Intent mIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            mContext.startActivity(mIntent);
                        }
                    })
                    .setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() {
                        public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                            mActivity.finish();
                        }
                    });
            final AlertDialog alert = builder.create();
            alert.show();
        }
    
    
        public Location getLastKnownLocation() {
            locationProvider = LocationManager.NETWORK_PROVIDER;
            Location lastKnownLocation = null;
            // Or use LocationManager.GPS_PROVIDER
            if (Build.VERSION.SDK_INT >= 23 &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return lastKnownLocation;
            }
            try {
                lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
                return lastKnownLocation;
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
            return lastKnownLocation;
        }
    
        public boolean isGooglePlayServicesAvailable() {
            int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);
    
            if (status == ConnectionResult.SUCCESS) {
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * Determines whether one Location reading is better than the current Location fix
         *
         * @param location            The new Location that you want to evaluate
         * @param currentBestLocation The current Location fix, to which you want to compare the new one
         */
        protected Location getBetterLocation(Location location, Location currentBestLocation) {
            if (currentBestLocation == null) {
                // A new location is always better than no location
                return location;
            }
    
            // Check whether the new location fix is newer or older
            long timeDelta = location.getTime() - currentBestLocation.getTime();
            boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
            boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
            boolean isNewer = timeDelta > 0;
    
            // If it's been more than two minutes since the current location, use the new location
            // because the user has likely moved
            if (isSignificantlyNewer) {
                return location;
                // If the new location is more than two minutes older, it must be worse
            } else if (isSignificantlyOlder) {
                return currentBestLocation;
            }
    
            // Check whether the new location fix is more or less accurate
            int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
            boolean isLessAccurate = accuracyDelta > 0;
            boolean isMoreAccurate = accuracyDelta < 0;
            boolean isSignificantlyLessAccurate = accuracyDelta > 200;
    
            // Check if the old and new location are from the same provider
            boolean isFromSameProvider = isSameProvider(location.getProvider(),
                    currentBestLocation.getProvider());
    
            // Determine location quality using a combination of timeliness and accuracy
            if (isMoreAccurate) {
                return location;
            } else if (isNewer && !isLessAccurate) {
                return location;
            } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
                return location;
            }
            return currentBestLocation;
        }
    
        /**
         * Checks whether two providers are the same
         */
    
        private boolean isSameProvider(String provider1, String provider2) {
            if (provider1 == null) {
                return provider2 == null;
            }
            return provider1.equals(provider2);
        }
    
        public boolean isLocationAccurate(Location location) {
            if (location.hasAccuracy()) {
                return true;
            } else {
                return false;
            }
        }
    
        public Location getStaleLocation() {
            if (mLastLocationFetched != null) {
                return mLastLocationFetched;
            }
            if (Build.VERSION.SDK_INT >= 23 &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return null;
            }
            if (mProviderType == SmartLocationManager.GPS_PROVIDER) {
                return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) {
                return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            } else {
                return getBetterLocation(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
            }
        }
    }
    

    we can use it with activity or a fragment, here i am using it with activity

    import android.location.Location;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.example.raza.locationaware.location.LocationManagerInterface;
    import com.example.raza.locationaware.location.SmartLocationManager;
    import com.google.android.gms.location.LocationRequest;
    
    public class LocationActivity extends AppCompatActivity implements LocationManagerInterface {
    
        public static final String TAG = LocationActivity.class.getSimpleName();
    
        SmartLocationManager mLocationManager;
        TextView mLocalTV, mLocationProviderTV, mlocationTimeTV;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_location);
            mLocationManager = new SmartLocationManager(getApplicationContext(), this, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE); // init location manager
            mLocalTV = (TextView) findViewById(R.id.locationDisplayTV);
            mLocationProviderTV = (TextView) findViewById(R.id.locationProviderTV);
            mlocationTimeTV = (TextView) findViewById(R.id.locationTimeFetchedTV);
        }
    
        protected void onStart() {
            super.onStart();
            mLocationManager.startLocationFetching();
        }
    
        protected void onStop() {
            super.onStop();
            mLocationManager.abortLocationFetching();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            mLocationManager.pauseLocationFetching();
        }
    
        @Override
        public void locationFetched(Location mLocal, Location oldLocation, String time, String locationProvider) {
            Toast.makeText(getApplication(), "Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude(), Toast.LENGTH_LONG).show();
            mLocalTV.setText("Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude());
            mLocationProviderTV.setText(locationProvider);
            mlocationTimeTV.setText(time);
        }
    }
    

    Hope it helps, if you can suggest any improvement kindly post it on git. Thanks.

    0 讨论(0)
  • 2020-11-21 05:00

    April 2020

    Full steps to get current location, and avoid Last Known Location nullability.

    According to official documentation, Last Known Location could be Null in case of:

    • Location is turned off in the device settings. As it clears the cache.
    • The device never recorded its location. (New device)
    • Google Play services on the device has restarted.

    In this case, you should requestLocationUpdates and receive the new location on the LocationCallback.

    By the following steps your last known Location never null.


    Pre-requisite: EasyPermission library


    Step 1: In manifest file add this permission

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    

    Step 2:

        override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    
        //Create location callback when it's ready.
        createLocationCallback()
    
        //createing location request, how mant request would be requested.
        createLocationRequest()
    
        //Build check request location setting request
        buildLocationSettingsRequest()
    
        //FusedLocationApiClient which includes location 
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
        //Location setting client
        mSettingsClient = LocationServices.getSettingsClient(this)
    
        //Check if you have ACCESS_FINE_LOCATION permission
        if (!EasyPermissions.hasPermissions(
                this@MainActivity,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            requestPermissionsRequired()
        }
        else{
            //If you have the permission we should check location is opened or not
            checkLocationIsTurnedOn()
        }
    
    }
    

    Step 3: Create required functions to be called in onCreate()

    private fun requestPermissionsRequired() {
        EasyPermissions.requestPermissions(
            this,
            getString(R.string.location_is_required_msg),
            LOCATION_REQUEST,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    }
    
    private fun createLocationCallback() {
        //Here the location will be updated, when we could access the location we got result on this callback.
        mLocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                super.onLocationResult(locationResult)
                mCurrentLocation = locationResult.lastLocation
            }
        }
    }
    
    private fun buildLocationSettingsRequest() {
        val builder = LocationSettingsRequest.Builder()
        builder.addLocationRequest(mLocationRequest!!)
        mLocationSettingsRequest = builder.build()
        builder.setAlwaysShow(true)
    }
    
    private fun createLocationRequest() {
        mLocationRequest = LocationRequest.create()
        mLocationRequest!!.interval = 0
        mLocationRequest!!.fastestInterval = 0
        mLocationRequest!!.numUpdates = 1
        mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
    
    public fun checkLocationIsTurnedOn() { // Begin by checking if the device has the necessary location settings.
        mSettingsClient!!.checkLocationSettings(mLocationSettingsRequest)
            .addOnSuccessListener(this) {
                Log.i(TAG, "All location settings are satisfied.")
                startLocationUpdates()
            }
            .addOnFailureListener(this) { e ->
                val statusCode = (e as ApiException).statusCode
                when (statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                        try {
                            val rae = e as ResolvableApiException
                            rae.startResolutionForResult(this@MainActivity, LOCATION_IS_OPENED_CODE)
                        } catch (sie: IntentSender.SendIntentException) {
                        }
                    }
                    LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                        mRequestingLocationUpdates = false
                    }
                }
            }
    }
    
    private fun startLocationUpdates() {
        mFusedLocationClient!!.requestLocationUpdates(
            mLocationRequest,
            mLocationCallback, null
        )
    }
    

    Step 4:

    Handle callbacks in onActivityResult() after ensuring the location is opened or the user accepts to open it in.

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            LOCATION_IS_OPENED_CODE -> {
                if (resultCode == AppCompatActivity.RESULT_OK) {
                    Log.d(TAG, "Location result is OK")
                } else {
                    activity?.finish()
                }
            }
    }
    

    Step 5: Get last known location from FusedClientApi

    override fun onMapReady(map: GoogleMap) {
        mMap = map
        mFusedLocationClient.lastLocation.addOnSuccessListener {
            if(it!=null){
                locateUserInMap(it)
            }
        }
    
    }
       private fun locateUserInMap(location: Location) {
        showLocationSafetyInformation()
        if(mMap!=null){
            val currentLocation = LatLng(location.latitude,location.longitude )
            addMarker(currentLocation)
        }
    }
    
    
    private fun addMarker(currentLocation: LatLng) {
        val cameraUpdate = CameraUpdateFactory.newLatLng(currentLocation)
        mMap?.clear()
        mMap?.addMarker(
            MarkerOptions().position(currentLocation)
                .title("Current Location")
        )
        mMap?.moveCamera(cameraUpdate)
        mMap?.animateCamera(cameraUpdate)
        mMap?.setMinZoomPreference(14.0f);
    }
    

    I hope this would help.

    Happy Coding

    0 讨论(0)
提交回复
热议问题