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


Translate

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


All Answers
  • Translate

    I have created a small application with step by step description to get current location's GPS coordinates.

    Complete example source code is in Get Current Location coordinates , City name - in Android.


    See how it works:

    • All we need to do is add this permission in the manifest file:

      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      
    • And create a LocationManager instance like this:

      LocationManager locationManager = (LocationManager)
      getSystemService(Context.LOCATION_SERVICE);
      
    • Check if GPS is enabled or not.

    • And then implement LocationListener and get coordinates:

      LocationListener locationListener = new MyLocationListener();
      locationManager.requestLocationUpdates(
      LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
      
    • Here is the sample code to do so


    /*---------- Listener class to get coordinates ------------- */
    private class MyLocationListener implements LocationListener {
    
        @Override
        public void onLocationChanged(Location loc) {
            editLocation.setText("");
            pb.setVisibility(View.INVISIBLE);
            Toast.makeText(
                    getBaseContext(),
                    "Location changed: Lat: " + loc.getLatitude() + " Lng: "
                        + loc.getLongitude(), Toast.LENGTH_SHORT).show();
            String longitude = "Longitude: " + loc.getLongitude();
            Log.v(TAG, longitude);
            String latitude = "Latitude: " + loc.getLatitude();
            Log.v(TAG, latitude);
    
            /*------- To get city name from coordinates -------- */
            String cityName = null;
            Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
            List<Address> addresses;
            try {
                addresses = gcd.getFromLocation(loc.getLatitude(),
                        loc.getLongitude(), 1);
                if (addresses.size() > 0) {
                    System.out.println(addresses.get(0).getLocality());
                    cityName = addresses.get(0).getLocality();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            String s = longitude + "\n" + latitude + "\n\nMy Current City is: "
                + cityName;
            editLocation.setText(s);
        }
    
        @Override
        public void onProviderDisabled(String provider) {}
    
        @Override
        public void onProviderEnabled(String provider) {}
    
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    }
    


  • Translate

    Here is additional information for other answers.

    Since Android has

    GPS_PROVIDER and NETWORK_PROVIDER
    

    you can register to both and start fetch events from onLocationChanged(Location location) from two at the same time. So far so good. Now the question do we need two results or we should take the best. As I know GPS_PROVIDER results have better accuracy than NETWORK_PROVIDER.

    Let's define Location field:

    private Location currentBestLocation = null;
    

    Before we start listen on Location change we will implement the following method. This method returns the last known location, between the GPS and the network one. For this method newer is best.

    /**
     * @return the last know best location
     */
    private Location getLastBestLocation() {
        Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    
        long GPSLocationTime = 0;
        if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); }
    
        long NetLocationTime = 0;
    
        if (null != locationNet) {
            NetLocationTime = locationNet.getTime();
        }
    
        if ( 0 < GPSLocationTime - NetLocationTime ) {
            return locationGPS;
        }
        else {
            return locationNet;
        }
    }
    

    Each time when we retrieve a new location we will compare it with our previous result.

    ...
    static final int TWO_MINUTES = 1000 * 60 * 2;
    ...
    

    I add a new method to onLocationChanged:

    @Override
    public void onLocationChanged(Location location) {
    
        makeUseOfNewLocation(location);
    
        if(currentBestLocation == null){
            currentBestLocation = location;
        }
    
        ....
    }
    
    
    /**
     * This method modify the last know good location according to the arguments.
     *
     * @param location The possible new location.
     */
    void makeUseOfNewLocation(Location location) {
        if ( isBetterLocation(location, currentBestLocation) ) {
            currentBestLocation = location;
        }
    }
    
    ....
    
    /** 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 boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new location is always better than no location
            return true;
        }
    
        // 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 true;
            // If the new location is more than two minutes older, it must be worse.
        } else if (isSignificantlyOlder) {
            return false;
        }
    
        // 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 true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }
    
    // Checks whether two providers are the same
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }
    
    ....
    

  • Translate

    You can find the location either by GPS_PROVIDER or NETWORK_PROVIDER.

    Overview of location services in Android.

    Here is one example which try to find the location using GPS. If your GPS is not available then try to use network for find the location.

    GPSTracker.java

     public class GPSTracker extends Service implements LocationListener {
    
        private final Context mContext;
    
        // Flag for GPS status
        boolean isGPSEnabled = false;
    
        // Flag for network status
        boolean isNetworkEnabled = false;
    
        // Flag for GPS status
        boolean canGetLocation = false;
    
        Location location; // Location
        double latitude; // Latitude
        double longitude; // Longitude
    
        // The minimum distance to change Updates in meters
        private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
    
        // The minimum time between updates in milliseconds
        private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
    
        // Declaring a Location Manager
        protected LocationManager locationManager;
    
        public GPSTracker(Context context) {
            this.mContext = context;
            getLocation();
        }
    
        public Location getLocation() {
            try {
                locationManager = (LocationManager) mContext
                        .getSystemService(LOCATION_SERVICE);
    
                // Getting GPS status
                isGPSEnabled = locationManager
                        .isProviderEnabled(LocationManager.GPS_PROVIDER);
    
                // Getting network status
                isNetworkEnabled = locationManager
                        .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
                if (!isGPSEnabled && !isNetworkEnabled) {
                    // No network provider is enabled
                } else {
                    this.canGetLocation = true;
                    if (isNetworkEnabled) {
                        locationManager.requestLocationUpdates(
                                LocationManager.NETWORK_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("Network", "Network");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                    // If GPS enabled, get latitude/longitude using GPS Services
                    if (isGPSEnabled) {
                        if (location == null) {
                            locationManager.requestLocationUpdates(
                                    LocationManager.GPS_PROVIDER,
                                    MIN_TIME_BW_UPDATES,
                                    MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                            Log.d("GPS Enabled", "GPS Enabled");
                            if (locationManager != null) {
                                location = locationManager
                                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                if (location != null) {
                                    latitude = location.getLatitude();
                                    longitude = location.getLongitude();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
    
            return location;
        }
    
    
        /**
         * Stop using GPS listener
         * Calling this function will stop using GPS in your app.
         * */
        public void stopUsingGPS(){
            if(locationManager != null){
                locationManager.removeUpdates(GPSTracker.this);
            }
        }
    
    
        /**
         * Function to get latitude
         * */
        public double getLatitude(){
            if(location != null){
                latitude = location.getLatitude();
            }
    
            // return latitude
            return latitude;
        }
    
    
        /**
         * Function to get longitude
         * */
        public double getLongitude(){
            if(location != null){
                longitude = location.getLongitude();
            }
    
            // return longitude
            return longitude;
        }
    
        /**
         * Function to check GPS/Wi-Fi enabled
         * @return boolean
         * */
        public boolean canGetLocation() {
            return this.canGetLocation;
        }
    
    
        /**
         * Function to show settings alert dialog.
         * On pressing the Settings button it will launch Settings Options.
         * */
        public void showSettingsAlert(){
            AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
    
            // Setting Dialog Title
            alertDialog.setTitle("GPS is settings");
    
            // Setting Dialog Message
            alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
    
            // On pressing the Settings button.
            alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,int which) {
                    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    mContext.startActivity(intent);
                }
            });
    
            // On pressing the cancel button
            alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
                }
            });
    
            // Showing Alert Message
            alertDialog.show();
        }
    
    
        @Override
        public void onLocationChanged(Location location) {
        }
    
    
        @Override
        public void onProviderDisabled(String provider) {
        }
    
    
        @Override
        public void onProviderEnabled(String provider) {
        }
    
    
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
    
    
        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
    }
    

    Activity -AndroidGPSTrackingActivity.java

        public class AndroidGPSTrackingActivity extends Activity {
    
        Button btnShowLocation;
    
        // GPSTracker class
        GPSTracker gps;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
    
            // Show location button click event
            btnShowLocation.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View arg0) {
                    // Create class object
                    gps = new GPSTracker(AndroidGPSTrackingActivity.this);
    
                    // Check if GPS enabled
                    if(gps.canGetLocation()) {
    
                        double latitude = gps.getLatitude();
                        double longitude = gps.getLongitude();
    
                        // \n is for new line
                        Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
                    } else {
                        // Can't get location.
                        // GPS or network is not enabled.
                        // Ask user to enable GPS/network in settings.
                        gps.showSettingsAlert();
                    }
                }
            });
        }
    }
    

    Layout- main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <Button android:id="@+id/btnShowLocation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Show Location"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"/>
    </RelativeLayout>
    

    AndroidManifest.xml

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

  • Translate

    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.


  • Translate

    Since I didn't like some of the code in the other answers, here's my simple solution. This solution is meant to be usable in an Activity or Service to track the location. It makes sure that it never returns data that's too stale unless you explicitly request stale data. It can be run in either a callback mode to get updates as we receive them, or in poll mode to poll for the most recent info.

    Generic LocationTracker interface. Allows us to have multiple types of location trackers and plug the appropriate one in easily:

    package com.gabesechan.android.reusable.location;
    
    import android.location.Location;
    
    public interface LocationTracker {
        public interface LocationUpdateListener{
            public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime);
        }
    
        public void start();
        public void start(LocationUpdateListener update);
    
        public void stop();
    
        public boolean hasLocation();
    
        public boolean hasPossiblyStaleLocation();
    
        public Location getLocation();
    
        public Location getPossiblyStaleLocation();
    
    }
    

    ProviderLocationTracker- this class will track the location for either GPS or NETWORK.

    package com.gabesechan.android.reusable.location;
    
    import android.content.Context;
    import android.location.Location;
    import android.location.LocationListener;
    import android.location.LocationManager;
    import android.os.Bundle;
    
    public class ProviderLocationTracker implements LocationListener, LocationTracker {
    
        // The minimum distance to change Updates in meters
        private static final long MIN_UPDATE_DISTANCE = 10; 
    
        // The minimum time between updates in milliseconds
        private static final long MIN_UPDATE_TIME = 1000 * 60; 
    
        private LocationManager lm;
    
        public enum ProviderType{
            NETWORK,
            GPS
        };    
        private String provider;
    
        private Location lastLocation;
        private long lastTime;
    
        private boolean isRunning;
    
        private LocationUpdateListener listener;
    
        public ProviderLocationTracker(Context context, ProviderType type) {
            lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
            if(type == ProviderType.NETWORK){
                provider = LocationManager.NETWORK_PROVIDER;
            }
            else{
                provider = LocationManager.GPS_PROVIDER;
            }
        }
    
        public void start(){
            if(isRunning){
                //Already running, do nothing
                return;
            }
    
            //The provider is on, so start getting updates.  Update current location
            isRunning = true;
            lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this);
            lastLocation = null;
            lastTime = 0;
            return;
        }
    
        public void start(LocationUpdateListener update) {
            start();
            listener = update;
    
        }
    
    
        public void stop(){
            if(isRunning){
                lm.removeUpdates(this);
                isRunning = false;
                listener = null;
            }
        }
    
        public boolean hasLocation(){
            if(lastLocation == null){
                return false;
            }
            if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
                return false; //stale
            }
            return true;
        }
    
        public boolean hasPossiblyStaleLocation(){
            if(lastLocation != null){
                return true;
            }
            return lm.getLastKnownLocation(provider)!= null;
        }
    
        public Location getLocation(){
            if(lastLocation == null){
                return null;
            }
            if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
                return null; //stale
            }
            return lastLocation;
        }
    
        public Location getPossiblyStaleLocation(){
            if(lastLocation != null){
                return lastLocation;
            }
            return lm.getLastKnownLocation(provider);
        }
    
        public void onLocationChanged(Location newLoc) {
            long now = System.currentTimeMillis();
            if(listener != null){
                listener.onUpdate(lastLocation, lastTime, newLoc, now);
            }
            lastLocation = newLoc;
            lastTime = now;
        }
    
        public void onProviderDisabled(String arg0) {
    
        }
    
        public void onProviderEnabled(String arg0) {
    
        }
    
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        }
    }
    

    The is the FallbackLocationTracker, which will track by both GPS and NETWORK, and use whatever location is more accurate.

    package com.gabesechan.android.reusable.location;
    
    import android.content.Context;
    import android.location.Location;
    import android.location.LocationManager;
    
    public class FallbackLocationTracker  implements LocationTracker, LocationTracker.LocationUpdateListener {
    
    
        private boolean isRunning;
    
        private ProviderLocationTracker gps;
        private ProviderLocationTracker net;
    
        private LocationUpdateListener listener;
    
        Location lastLoc;
        long lastTime;
    
        public FallbackLocationTracker(Context context) {
            gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
            net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
        }
    
        public void start(){
            if(isRunning){
                //Already running, do nothing
                return;
            }
    
            //Start both
            gps.start(this);
            net.start(this);
            isRunning = true;
        }
    
        public void start(LocationUpdateListener update) {
            start();
            listener = update;
        }
    
    
        public void stop(){
            if(isRunning){
                gps.stop();
                net.stop();
                isRunning = false;
                listener = null;
            }
        }
    
        public boolean hasLocation(){
            //If either has a location, use it
            return gps.hasLocation() || net.hasLocation();
        }
    
        public boolean hasPossiblyStaleLocation(){
            //If either has a location, use it
            return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
        }
    
        public Location getLocation(){
            Location ret = gps.getLocation();
            if(ret == null){
                ret = net.getLocation();
            }
            return ret;
        }
    
        public Location getPossiblyStaleLocation(){
            Location ret = gps.getPossiblyStaleLocation();
            if(ret == null){
                ret = net.getPossiblyStaleLocation();
            }
            return ret;
        }
    
        public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
            boolean update = false;
    
            //We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
            if(lastLoc == null){
                update = true;
            }
            else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
                update = true;
            }
            else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
                update = true;
            }
            else if (newTime - lastTime > 5 * 60 * 1000){
                update = true;
            }
    
            if(update){
                if(listener != null){
                    listener.onUpdate(lastLoc, lastTime, newLoc, newTime);                  
                }
                lastLoc = newLoc;
                lastTime = newTime;
            }
    
        }
    }
    

    Since both implement the LocationTracker interface, you can easily change your mind about which one to use. To run the class in poll mode, just call start(). To run it in update mode, call start(Listener).

    Also take a look at my blog post on the code


  • Translate

    Get location of gps by -

    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    
    LocationListener locationListener = new LocationListener() 
    {
    
                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public void onProviderEnabled(String provider) {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public void onProviderDisabled(String provider) {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public void onLocationChanged(Location location) {
                    // TODO Auto-generated method stub
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();
                    double speed = location.getSpeed(); //spedd in meter/minute
                    speed = (speed*3600)/1000;      // speed in km/minute               Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show();
                }
            };
    
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    
    }
    

  • Translate

    You need to use latest/newest

    GoogleApiClient Api

    Basically what you need to do is:

    private GoogleApiClient mGoogleApiClient;
    mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
    

    Then

    @Override
        public void onConnected(Bundle connectionHint) {
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                    mGoogleApiClient);
            if (mLastLocation != null) {
                mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
                mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
            }
        }
    

    for the most accurate and reliable location. See my post here:

    https://stackoverflow.com/a/33599228/2644905

    Do not use LocationListener which is not accurate and has delayed response. To be honest this is easier to implement. Also read documentation: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient


  • Translate
    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...


  • Translate

    Now that Google Play locations services are here, I recommend that developers start using the new fused location provider. You will find it easier to use and more accurate. Please watch the Google I/O video Beyond the Blue Dot: New Features in Android Location by the two guys who created the new Google Play location services API.

    I've been working with location APIs on a number of mobile platforms, and I think what these two guys have done is really revolutionary. It's gotten rid of a huge amount of the complexities of using the various providers. Stack Overflow is littered with questions about which provider to use, whether to use last known location, how to set other properties on the LocationManager, etc. This new API that they have built removes most of those uncertainties and makes the location services a pleasure to use.

    I've written an Android app that periodically gets the location using Google Play location services and sends the location to a web server where it is stored in a database and can be viewed on Google Maps. I've written both the client software (for Android, iOS, Windows Phone and Java ME) and the server software (for ASP.NET and SQL Server or PHP and MySQL). The software is written in the native language on each platform and works properly in the background on each. Lastly, the software has the MIT License. You can find the Android client here:

    https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android


  • Translate

    Simplest you can find

       package com.javapapers.android.geolocationfinder;
    
        import android.os.Bundle;
        import android.app.Activity;
        import android.content.Context;
        import android.location.Location;
        import android.location.LocationListener;
        import android.location.LocationManager;
        import android.widget.TextView;
    
        import android.util.Log;
    
        public class MainActivity extends Activity implements LocationListener{
        protected LocationManager locationManager;
        protected LocationListener locationListener;
        protected Context context;
        TextView txtLat;
        String lat;
        String provider;
        protected String latitude,longitude; 
        protected boolean gps_enabled,network_enabled;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txtLat = (TextView) findViewById(R.id.textview1);
    
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
        @Override
        public void onLocationChanged(Location location) {
        txtLat = (TextView) findViewById(R.id.textview1);
        txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
        }
    
        @Override
        public void onProviderDisabled(String provider) {
        Log.d("Latitude","disable");
        }
    
        @Override
        public void onProviderEnabled(String provider) {
        Log.d("Latitude","enable");
        }
    
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        Log.d("Latitude","status");
        }
        }
    

  • Translate

    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


  • Translate

    Getting location updates requires lots of bolierplate code in Android, You need to take care of

    • Google Play services availablity Check,
    • Update Google play Service if it is old or not available
    • Dialog Creation of GoogleApiClient and its callbacks connected,disconnected etc.
    • Stopping and releasing resources for location updates
    • Handling Location permission scenarios
    • Checking Location services are On or Off
    • Getting lastknown location is not so easy either
    • Fallback to last known location if not getting location after certain duration

    To ease out all these steps i have created Android-EasyLocation (small android library) which will take care all this stuff and you can focus on business logic.

    All you need is extend EasyLocationActivity and this

    requestSingleLocationFix(easyLocationRequest);
    

    or

    requestLocationUpdates(easyLocationRequest);
    

    Checkout sample app and steps needed here at https://github.com/akhgupta/Android-EasyLocation


  • Translate

    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.


  • Translate

    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


  • Translate

    If you are creating new location projects for Android you should use the new Google Play location services. It is much more accurate and much simpler to use.

    I have been working on an open source GPS tracker project, GpsTracker, for several years. I recently updated it to handle periodic updates from Android, iOS, Windows Phone and Java ME cell phones. It is fully functional and does what you need and has the MIT License.

    The Android project within GpsTracker uses the new Google Play services and there are also two server stacks (ASP.NET and PHP) to allow you to track those phones.


  • Translate

    For just location checking you can use following code. You can put it in your onStart() of main activity and display alert dialog if return is false.

    private boolean isLocationAccurate()
        {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
            {
                String provider = Settings.Secure
                        .getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
                if (provider != null && !provider.contains("gps"))
                {
                    return false;
                }
            }
            else
            {
                try
                {
                    int status = Settings.Secure
                            .getInt(this.getContentResolver(), Settings.Secure.LOCATION_MODE);
                    if (status != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY)
                    {
                        return false;
                    }
                }
                catch (Settings.SettingNotFoundException e)
                {
                    Log.e(TAG, e.getMessage());
                }
            }
    
            return true;
        }
    

  • Translate

    I have published a small library that can make it easy to get location data in Android, it even takes care of Android M runtime permissions.

    You might check it out here: https://github.com/julioromano/RxLocation and use it or its source code as examples for your implementation.


  • Translate

    Simple Find Write Code in On Location Method

    public void onLocationChanged(Location location) {
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }
    
    
        //Place current location marker
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
        mCurrLocationMarker = mMap.addMarker(markerOptions);
    
        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
    
        PolylineOptions pOptions = new PolylineOptions()
                .width(5)
                .color(Color.GREEN)
                .geodesic(true);
        for (int z = 0; z < routePoints.size(); z++) {
            LatLng point = routePoints.get(z);
            pOptions.add(point);
        }
        line = mMap.addPolyline(pOptions);
        routePoints.add(latLng);
    }
    

  • Translate

    I have got very accurate location using FusedLocationProviderClient
    (Google Play services required)

    Permissions Required

    android.permission.ACCESS_FINE_LOCATION

    android.permission.ACCESS_COARSE_LOCATION

    Dependency

    'com.google.android.gms:play-services-location:15.0.0'

    Kotlin Code

    val client = FusedLocationProviderClient(this)
    val location = client.lastLocation
    location.addOnCompleteListener {
        // this is a lambda expression and we get an 'it' iterator to access the 'result'
        // it.result.latitude gives the latitude
        // it.result.longitude gives the longitude 
        val geocoder = Geocoder(applicationContext, Locale.getDefault())
        val address = geocoder.getFromLocation(it.result.latitude, it.result.longitude, 1)
        if (address != null && address.size > 0) {
            // Get the current city
            city = address[0].locality
        }
    }
    location.addOnFailureListener {
        // Some error in getting the location, let's log it
        Log.d("xtraces", it.message)
    }
    

  • Translate

    I will recommend using Smart Location Library
    Very simple to use and it wraps the location logic nicely.

    For starting the location service:

    SmartLocation.with(context).location()
        .start(new OnLocationUpdatedListener() { ... });
    

    If you just want to get a single location (not periodic) you can just use the oneFix modifier. Example:

    SmartLocation.with(context).location()
        .oneFix()
        .start(new OnLocationUpdatedListener() { ... });
    

  • Translate

    Simple and easy way,

    Get location using https://github.com/sachinvarma/EasyLocation.

    Step 1: Just call

    new EasyLocationInit(MainActivity.this, timeInterval, fastestTimeInterval, runAsBackgroundService);
    

    timeInterval -> setInterval(long)(inMilliSeconds) means - set the interval in which you want to get locations.

    fastestTimeInterval -> setFastestInterval(long)(inMilliSeconds) means - if a location is available sooner you can get it. (i.e. another app is using the location services).

    runAsBackgroundService = True -> (Service will run in Background and updates Frequently(according to the timeInterval and fastestTimeInterval)) runAsBackgroundService = False -> (Service will getDestroyed after a successful location update )

    Step 2: Prepare EventBus subscribers: Declare and annotate your subscribing method, optionally specify a thread mode:

    eg:

         @Override
         public void onStart() {
             super.onStart();
             EventBus.getDefault().register(this);
         }
    
         @Override
         public void onStop() {
             super.onStop();
             EventBus.getDefault().unregister(this);
         }
    
      @SuppressLint("SetTextI18n")
      @Subscribe
      public void getEvent(final Event event) {
    
        if (event instanceof LocationEvent) {
          if (((LocationEvent) event).location != null) {
            ((TextView) findViewById(R.id.tvLocation)).setText("The Latitude is "
              + ((LocationEvent) event).location.getLatitude()
              + " and the Longitude is "
              + ((LocationEvent) event).location.getLongitude());
          }
        }
      }
    

    That's all.

    Hope it will help someone in future.


  • Translate

    Best way to fetch location is below

    // put dependancy
     implementation 'com.google.android.gms:play-services-location:11.0.4'
    
    // PUT permissions in Menifest
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    
    
    // create a Java file as below
    
    public class SingleShotLocationProvider {
    
      public static interface LocationCallback {
          public void onNewLocationAvailable(GPSCoordinates location);
      }
    
       // calls back to calling thread, note this is for low grain: if you want higher precision, swap the
       // contents of the else and if. Also be sure to check gps permission/settings are allowed.
       // call usually takes <10ms
    
      public static void requestSingleUpdate(final Context context, final LocationCallback callback) {
        final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (isNetworkEnabled) {
            Criteria criteria = new Criteria();
            criteria.setAccuracy(Criteria.ACCURACY_COARSE);
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    
                return;
            }
            locationManager.requestSingleUpdate(criteria, new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
                }
    
                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {
                }
    
                @Override
                public void onProviderEnabled(String provider) {
                }
    
                @Override
                public void onProviderDisabled(String provider) {
                }
            }, null);
         } else {
            boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            if (isGPSEnabled) {
                Criteria criteria = new Criteria();
                criteria.setAccuracy(Criteria.ACCURACY_FINE);
                locationManager.requestSingleUpdate(criteria, new LocationListener() {
                    @Override
                    public void onLocationChanged(Location location) {
                        callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
                    }
    
                    @Override public void onStatusChanged(String provider, int status, Bundle extras) { }
                    @Override public void onProviderEnabled(String provider) { }
                    @Override public void onProviderDisabled(String provider) { }
                }, null);
            }
         }
      }
    
    
      // consider returning Location instead of this dummy wrapper class
      public static class GPSCoordinates {
         public float longitude = -1;
         public float latitude = -1;
    
         public GPSCoordinates(float theLatitude, float theLongitude) {
            longitude = theLongitude;
            latitude = theLatitude;
         }
    
         public GPSCoordinates(double theLatitude, double theLongitude) {
            longitude = (float) theLongitude;
            latitude = (float) theLatitude;
         }
      }
    
    }
    // FILE FINISHED
    
    
    // FETCH LOCATION FROM ACTIVITY AS BELOW
    public void getLocation(Context context) {
        MyApplication.log(LOG_TAG, "getLocation() ");
    
        SingleShotLocationProvider.requestSingleUpdate(context,
                new SingleShotLocationProvider.LocationCallback() {
                    @Override
                    public void onNewLocationAvailable(SingleShotLocationProvider.GPSCoordinates loc) {
                        location = loc;
                        MyApplication.log(LOG_TAG, "getLocation() LAT: " + location.latitude + ", LON: " + location.longitude);               
                    }
                });
    }
    

  • Translate

    Implementation of Google API Location Services

    The method that will initialize and start Google API Client:

    private void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
        mGoogleApiClient.connect();
    }
    

    The method that will initialize and return LocationRequest:

    private LocationRequest getLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(Constants.GPS_UPDATE_TIME);
        mLocationRequest.setSmallestDisplacement(Constants.SMALLEST_DISTANCE);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }
    

    The method that will ask for the regular location update:

    private void startGettingLocations() {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
    

    After performing the actions stated above, as in the case of LocationManager, we are ready to get location updates using the onLocationChanged(Location location) method.

    LocationManager vs Google Play Services

    The source is here