Android best way to get current location

Amarnath picture Amarnath · Mar 27, 2013 · Viewed 25.6k times · Source

What is the best way to get the current location in android for the following scenario,

  1. If GPS is not available, get location from Network provider

  2. If GPS is available and can get current location, get location from GPS provider

  3. If GPS is available but can't get current location(i.e continuously searching location), get location from the network provider.

    now i can getting a location from network if gps not available, the best answer to satisfy the above scenario is highly appreciated. thanks in advance.

Answer

Nitish picture Nitish · Mar 27, 2013

Well, you can use Timer and TimerTask classes.

LocationManager manager;
TimerTask mTimertask;
GPSLocationListener mGPSLocationListener;
int i = 0; //Here i works as counter;
private static final int MAX_ATTEMPTS = 250;

public void getCurrentLocation() {
    manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    mGPSLocationListener = new GPSLocationListener();

    manager.addGpsStatusListener(mGPSStatusListener);
    mTimerTask = new LocTimerTask(LocationManager.GPS_PROVIDER);

    if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        Log.v(TAG, "GPS ENABLED");
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,
                50.0f, mGPSLocationListener);
    } else {
        turnGPSOn();
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,
                50.0f, mGPSLocationListener);
    }
    
    if(manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000L,
                50.0f, mNetworkLocationListener);
    }

    if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        Log.v(TAG, "GPS ENABLED");
        manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                1000L, 50.0f, mGPSLocationListener);
    }

    myLocTimer = new Timer("LocationRunner", true);
    myLocTimer.schedule(mTimerTask, 0, 500);
}

GPSStatusListener

private GpsStatus.Listener mGPSStatusListener = new GpsStatus.Listener() {

    @Override
    public synchronized void onGpsStatusChanged(int event) {
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            Log.v(TAG, "GPS SAtellitestatus");
            GpsStatus status = manager.getGpsStatus(null);
            mSattelites = 0;
            Iterable<GpsSatellite> list = status.getSatellites();
            for (GpsSatellite satellite : list) {
                if (satellite.usedInFix()) {
                    mSattelites++;
                }
            }
            break;

        case GpsStatus.GPS_EVENT_FIRST_FIX:
            /*
             * Toast.makeText(getApplicationContext(), "Got First Fix",
             * Toast.LENGTH_LONG).show();
             */
            break;

        case GpsStatus.GPS_EVENT_STARTED:
            /*
             * Toast.makeText(getApplicationContext(), "GPS Event Started",
             * Toast.LENGTH_LONG).show();
             */
            break;

        case GpsStatus.GPS_EVENT_STOPPED:
            /*
             * Toast.makeText(getApplicationContext(), "GPS Event Stopped",
             * Toast.LENGTH_LONG).show();
             */
            break;
        default:
            break;
        }
    }
};

LocationListener

public class GPSLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location argLocation) {
        location = argLocation;
    }

    public void onProviderDisabled(String provider) {

    }

    public void onProviderEnabled(String provider) {

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {

    }
}

TimerTask class

class LocTimerTask extends TimerTask {
    String provider;

    public LocTimerTask(String provider) {
        this.provider = provider;
    }

    final Handler mHandler = new Handler(Looper.getMainLooper());

    Runnable r = new Runnable() {
        @Override
        public void run() {
            i++;
            Log.v(TAG, "Timer Task run" + i);
            location = manager.getLastKnownLocation(provider);

            if (location != null) {
                Log.v(TAG, "in timer task run in if location not null");
                isGPS = true;
                onLocationReceived(location);
                myLocTimer.cancel();
                myLocTimer.purge();
                mTimerTask.cancel();
                return;
            } else {
                Log.v(TAG, "in timer task run in else location null");
                isGPS = false;
                if (location == null && i == MAX_ATTEMPTS) {
                    Log.v(TAG, "if 1 max attempts done");
                    turnGPSOff();
                    location = manager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        Log.v(TAG,
                                "if 1 max attempts done Location from network not null");
                        Log.v(TAG,
                                "if 1 max attempts done Location from network not null coordinates not null");
                        onLocationReceived(location);
                        myLocTimer.cancel();
                        myLocTimer.purge();
                        mTimerTask.cancel();
                        return;
                    }
                } else {
                    return;
                }
            }
            i = 0;
        }
    };

    public void run() {
        mHandler.post(r);
    }
}

Here the timer has been scheduled to run on every 500 milliseconds. Means, on every 500 milliseconds the timer task's run method will executed. In run method try get location from GPS provider for specific no. of attempts(Here MAX_ATTEMPTS) say 5 or 10. If it gets location within specified no. of attempts then use that location else if counter(Here i) value has exceeded MAX_ATTEMPTS, then get location from Network Provider. on getting location, I had passed that location to callback method onLocationReceived(Location mLoc) in which you can do your further work with location data. Here's how you will use callback method:

Listener

public interface OnLocationReceivedListener {
public void onLocationReceived(Location mLoc); //callback method which will be defined in your class.

}

Your class should implement the above defined listener. In your class:

@Override
public void onLocationReceived(Location mLoc) {
    //Do your stuff
}

Hope it helps. If anybody have a better approach, then please let me know.