Android Location Providers - Gps or Network Provider

Android Location Providers - GPS or Network Provider?


There are 3 location providers in Android.

They are:

gps –> (GPS, AGPS): Name of the GPS location provider. This
provider determines location using satellites. Depending on
conditions, this provider may take a while to return a location fix.
Requires the permission android.permission.ACCESS_FINE_LOCATION.

network –> (AGPS, CellID, WiFi MACID): Name of the network
location provider. This provider determines location based on
availability of cell tower and WiFi access points. Results are
retrieved by means of a network lookup. Requires either of the
permissions android.permission.ACCESS_COARSE_LOCATION or
android.permission.ACCESS_FINE_LOCATION.

passive –> (CellID, WiFi MACID): A special location provider for
receiving locations without actually initiating a location fix. This
provider can be used to passively receive location updates when other
applications or services request them without actually requesting the
locations yourself. This provider will return locations generated by
other providers. Requires the permission
android.permission.ACCESS_FINE_LOCATION, although if the GPS is not
enabled this provider might only return coarse fixes. This is what
Android calls these location providers, however, the underlying
technologies to make this stuff work is mapped to the specific set of
hardware and telco provided capabilities (network service).

The best way is to use the “network” or “passive” provider first,
and then fallback on “gps”, and depending on the task, switch between
providers. This covers all cases, and provides a lowest common
denominator service (in the worst case) and great service (in the best
case).

Sample Image

Article Reference : Android Location Providers - gps, network, passive By Nazmul Idris

Code Reference : https://stackoverflow.com/a/3145655/28557

-----------------------Update-----------------------

Now Android have Fused location provider

The Fused Location Provider intelligently manages the underlying location technology and gives you the best location according to your needs. It simplifies ways for apps to get the user’s current location with improved accuracy and lower power usage

Fused location provider provide three ways to fetch location

  1. Last Location: Use when you want to know current location once.
  2. Request Location using Listener: Use when application is on screen / frontend and require continues location.
  3. Request Location using Pending Intent: Use when application in background and require continues location.

References :

Official site : http://developer.android.com/google/play-services/location.html

Fused location provider example:
GIT : https://github.com/kpbird/fused-location-provider-example

http://blog.lemberg.co.uk/fused-location-provider

--------------------------------------------------------

How to get location either from GPS or NETWORK providers in android

You should first check before getting location from both. First check if location is available through gps and if not then use network to get location.
Here is a sample class which have methods for checking location.

    public class GPSTracker extends Service implements LocationListener {

private final Context context;

boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
public boolean canGetLocation = false;

Location location;

double latitude;
double longitude;

private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;

protected LocationManager locationManager;

public GPSTracker(Context context) {
this.context = context;
getLocation();
}

public Location getLocation() {
try {
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);

isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

if(!isGPSEnabled && !isNetworkEnabled) {

} else {
this.canGetLocation = true;

if (isNetworkEnabled) {

locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

if (location != null) {

latitude = location.getLatitude();
longitude = location.getLongitude();
}
}

}

if(isGPSEnabled) {
if(location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
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;
}


public void stopUsingGPS() {
if(locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}

public double getLatitude() {
if(location != null) {
latitude = location.getLatitude();
}
return latitude;
}

public double getLongitude() {
if(location != null) {
longitude = location.getLongitude();
}

return longitude;
}

public boolean canGetLocation() {
return this.canGetLocation;
}

public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);

alertDialog.setTitle("GPS is settings");

alertDialog.setMessage("Turn on your GPS to find nearby helpers");

alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});

alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});

alertDialog.show();
}

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

}

@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub

}

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}

}

Use GPS and Network Provider at the same time in Android

You can certainly use the same listener for multiple providers. It may be better to use locationmanager.getProviders with a Criteria object then sort by accuracy or just listen to all of them. Not much practical difference though.

The onLocationChanged callback gives you a Location object, which has a getProvider() method you can use to determine where it came from. It also has a getAccuracy() method, so you could also sort your recent fixes by accuracy.

LocationManager, GPS and Network providers.. are triggered both?

This is what I used for one of my projects and is perfectly working:

public Location getLocation() {
try {
mLocationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);

// getting GPS status
boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

// getting network status
boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
// First get location from Network Provider
if (isNetworkEnabled) {
mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (mLocationManager != null) {
location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
lat = location.getLatitude();
lng = location.getLongitude();
}
}
}
//get the location by gps
if (isGPSEnabled) {
if (location == null) {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (mLocationManager != null) {location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
lat = location.getLatitude();
lng = location.getLongitude();
}
}
}
}
}

} catch (Exception e) {
e.printStackTrace();
}

return location;
}

Obtain GPS or Network provider from Fused Location Provider


Is there a way I can get the provider from this?

You are. It is the fused provider. The locations provided by the fused provider are computed based not only on the GPS and network providers but other data sources as well, using proprietary algorithms.

How to use both GPS and Network Provider to get current location Latitude and Longitude values in Android


package loca.loca;

import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;


public class LocationActivity extends Activity {

double x,y;

Timer timer;
LocationManager lm;
boolean gps_enabled = false;
boolean network_enabled = false;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);


lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);



gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);



if (!gps_enabled && !network_enabled) { Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "nothing is enabled", duration);
toast.show();

}




if (gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locationListenerGps);
if (network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
locationListenerNetwork);
timer=new Timer();
timer.schedule(new GetLastLocation(), 20000);

}

LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer.cancel();
x =location.getLatitude();
y = location.getLongitude();
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);

Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "gps enabled "+x + "\n" + y, duration);
toast.show();
}

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) {
timer.cancel();
x = location.getLatitude();
y = location.getLongitude();
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);

Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "network enabled"+x + "\n" + y, duration);
toast.show();
}

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())
{x = gps_loc.getLatitude();
y = gps_loc.getLongitude();
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "gps lastknown "+x + "\n" + y, duration);
toast.show();
}
else
{x = net_loc.getLatitude();
y = net_loc.getLongitude();
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "network lastknown "+x + "\n" + y, duration);
toast.show();

}

}

if(gps_loc!=null){
{x = gps_loc.getLatitude();
y = gps_loc.getLongitude();
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "gps lastknown "+x + "\n" + y, duration);
toast.show();
}

}
if(net_loc!=null){
{x = net_loc.getLatitude();
y = net_loc.getLongitude();
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "network lastknown "+x + "\n" + y, duration);
toast.show();

}
}
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, "no last know avilable", duration);
toast.show();

}
}}

How Fused Location determines if use GPS or Network provider?

Well the library itself is not open-source, but I'm sure we can agree on how it does what your describe above:

If the GPS provider is disabled, or if the signal is too weak, or if the fix takes too long, then it returns the last known location and/or the network provider's location.

Seems reasonable. I guess the network provider serves as a fallback to the GPS provider in PRIORITY_HIGH_ACCURACY if GPS is not satisfying.

EDIT

Actually, the documentation says:

PRIORITY_HIGH_ACCURACY

This will return the finest location available.

It does not say it will only use GPS or prioritize GPS at all. It will just return the finest location, which is not always GPS, as @cYrixmorten pointed out: in urban areas, wifi spots are often more accurate.



Related Topics



Leave a reply



Submit