Prathyusha Prathyusha - 6 months ago 17
Android Question

How to get accurate gps location in android

I am developing an app where I need to show the exact and the most accurate location in maps. I tried using GPS_PROVIDER which gives 100mtrs distance from the location. can you guys please suggest me how to get the exact location.

here is my code

MainActivity:

public class MainActivity extends Activity implements LocationListener
{

private GoogleMap googleMap;
LocationManager locationManager;
double lat,longit;

private final float MIN_DISTANCE = 6;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

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


//locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, MIN_DISTANCE, this);

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,50,5,this);

//locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);


GPSTracker gpsTracker = new GPSTracker(this);

if(gpsTracker.canGetLocation)
{
lat = gpsTracker.latitude;
longit = gpsTracker.longitude;

System.out.println("latitude" +lat + "longitude" +longit);

Toast.makeText(getApplicationContext(), "latitude" +lat + "longitude" +longit, Toast.LENGTH_LONG).show();

}
else
{
gpsTracker.showSettingsAlert();
}
try
{
initializeMap();
}
catch(Exception e)
{
e.printStackTrace();
}
}


private void initializeMap()
{

if(googleMap == null)
{

googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

/*double latitude = 17.385044;
double longitude = 78.486671;*/

String abc = "Hello Maps";

MarkerOptions marker = new MarkerOptions().position(new LatLng(lat, longit)).title(abc);

//MarkerOptions marker = new MarkerOptions().position(new LatLng(17.426836, 78.549902)).title(abc);

googleMap.addMarker(marker);

marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));


if(googleMap == null)
{
Toast.makeText(getApplicationContext(), "Sorry unable to create", Toast.LENGTH_LONG).show();
}
}

// TODO Auto-generated method stub

}

@Override
protected void onResume() {
super.onResume();
initializeMap();
}


@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub

if(location.hasAccuracy())
{
return;
}
if(location.getAccuracy()>5)
{
return;

}

}


@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

}


GPSTracker:

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;

boolean canGetLocation = false;

Location location;
double latitude;
double longitude;

//The minimum distance to change updates in metters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; //10 metters

//The minimum time beetwen 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;

//First get location from Network Provider
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);
updateGPSCoordinates();
}
}

//if GPS Enabled get lat/long 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);
updateGPSCoordinates();
}
}
}
}
}
catch (Exception e)
{
//e.printStackTrace();
Log.e("Error : Location", "Impossible to connect to LocationManager", e);
}

return location;
}

public void updateGPSCoordinates()
{
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}

/**
* 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;
}

/**
* Function to get longitude
*/
public double getLongitude()
{
if (location != null)
{
longitude = location.getLongitude();
}

return longitude;
}

/**
* Function to check GPS/wifi enabled
*/
public boolean canGetLocation()
{
return this.canGetLocation;
}

/**
* Function to show settings alert dialog
*/
public void showSettingsAlert()
{
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

//Setting Dialog Title
alertDialog.setTitle("LAT Long");

//Setting Dialog Message
alertDialog.setMessage("GPS Message");

//On Pressing Setting button
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});

//On pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.cancel();
}
});

alertDialog.show();
}

/**
* Get list of address by latitude and longitude
* @return null or List<Address>
*/
public List<Address> getGeocoderAddress(Context context)
{
if (location != null)
{
Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
try
{
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
return addresses;
}
catch (IOException e)
{
//e.printStackTrace();
Log.e("Error : Geocoder", "Impossible to connect to Geocoder", e);
}
}

return null;
}

/**
* Try to get AddressLine
* @return null or addressLine
*/
public String getAddressLine(Context context)
{
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0)
{
Address address = addresses.get(0);
String addressLine = address.getAddressLine(0);

return addressLine;
}
else
{
return null;
}
}

/**
* Try to get Locality
* @return null or locality
*/
public String getLocality(Context context)
{
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0)
{
Address address = addresses.get(0);
String locality = address.getLocality();

return locality;
}
else
{
return null;
}
}

/**
* Try to get Postal Code
* @return null or postalCode
*/
public String getPostalCode(Context context)
{
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0)
{
Address address = addresses.get(0);
String postalCode = address.getPostalCode();

return postalCode;
}
else
{
return null;
}
}

/**
* Try to get CountryName
* @return null or postalCode
*/
public String getCountryName(Context context)
{
List<Address> addresses = getGeocoderAddress(context);
if (addresses != null && addresses.size() > 0)
{
Address address = addresses.get(0);
String countryName = address.getCountryName();

return countryName;
}
else
{
return null;
}
}

@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 intent)
{
return null;
}


}


please help me out

Thanks in advance

Answer

In the actual state of things, you will never get a GPS location after you have a network location. location will never be null in your second condition, because it was already set by the network provider. In short, your app is just never fetching the user's location from the GPS provider (see comment below).

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);
        updateGPSCoordinates();
    }
}

//if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled)
{
    // Location will most likely never be null here, since it was fetched first by the network provider above
    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);
            updateGPSCoordinates();
        }
    }
}

Most importantly, this code is in the wrong place, it should go in the onLocationChanged(Location location) method so it runs every time there is a location update. Leaving it there to get a preliminary location can be interesting though. I suggest you change the code to something like this:

//if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled)
{
        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);
            updateGPSCoordinates();
        }
    }
} else 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);
        updateGPSCoordinates();
    }
}

// ...

@Override
public void onLocationChanged(Location location) 
{ 
    this.location = location;
    updateGPSCoordinates();
}