Greetings,
Does anyone know how I can get coarse GPS coordinates when I don't have a fix and get fine GPS coordinates when I have a fix?
I've tried googling for some sample code to no avail.
I did find this: http://www.android10.org/index.php/articleslocationmaps/226-android-location-providers-gps-network-passive
But I don't know how to implement the fallback to coarse/upgrade to fine.
I hope someone can help. Thanks in advance,
You can find an excellent introduction to the subject in the documentation. The basic idea is that you enable listening for updates from different providers. When a new location is received, you compare it to the previous stored location (a sample function is provided in the above link).
A location object has an getAccuracy that you can use to measure its accuracy. You should also set up a timer so that you know how long has passed after a location provider has provided an update. If more than two minutes have passed after GPS provider has given you an update, then start listening for network updates. While listening for network updates, if GPS gives you a new update, then switch to fine location.
You can get the last know location using the code below. It gets the location providers and loops over the array backwards. i.e starts with GPS, if no GPS then gets network location. You can call this method whenever you need to get the location.
private double[] getGPS() {
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/* Loop over the array backwards, and if you get an accurate location, then break out the loop*/
Location l = null;
for (int i=providers.size()-1; i>=0; i--) {
l = lm.getLastKnownLocation(providers.get(i));
if (l != null) break;
}
double[] gps = new double[2];
if (l != null) {
gps[0] = l.getLatitude();
gps[1] = l.getLongitude();
}
return gps;
}
Related
I am trying to make a simple app that revolves around tracking someone's speed. I have read through Android Studio's Location guide, however it doesn't show how to get someone's speed, or get someone's location at an even interval.
Currently, I have this snippet of code set up:
if (OldLocation != null) {
OldLocation = NewLocation;
NewLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
} else {
OldLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
try {Thread.sleep(1000);} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
NewLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
float distance = OldLocation.distanceTo(NewLocation);
float speed = distance / 1000;
I am currently using Thread.sleep to do this, though I think there would be a better way to request updates periodically.
Can anyone show me how?
That is the worst way you can possible do it. For a dozen reasons you should almost never use getLastKnownLocation- and getting continual updates is definitely NOT one of those places to do it. Instead, use LocationManager.requestLocationUpdates(). You provide it a callback object and it calls you when an updated position is available.
Also, use LocationManager or the Google Play Fused Location. There's no good reason to mix and match.
I have a timer that runs every second. Every second I get the GPS location and do other stuffs.
I am wondering which way is better:
1- Request a single location update and then get the last known location
private void timeout(){
String data[] =new String[DATA_LENGTH];
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, null);
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
.
.
.
}
2- Start Location listener and then just get the last known location whenever my timer expire
OnCreate(){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
private void timeout(){
String data[] =new String[DATA_LENGTH];
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
.
.
.
}
Thank you
PS: Note that battery is not a concern to me as per the requirement of the product
requestSingleUpdate is meant to be single, if you need to query the GPS frequently you should definitely go with option 2.
Keep a global Location object in memory, use it in you other stuff and update it whenever your listener gets an update from the LocationManager.
You can listen for changes via requestLocationUpdates - the code below is a quick-n-dirty example (untested). Remember, you have to have location services turned on to use this.
LocationListener locGPSListener= new LocationListener() {...}
LocationListener locNetworkListener= new LocationListener() {...}
mgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// listens using GPS for location
mgr .requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locGPSListener);
// uses towers for location
mgr .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locNetworkListener);
...
What approach is better, depends on
Androids GPS behaviour and
your Application.
ad 1. if explicitly getting a location delivers a more recent fix, than this is an advantage, because:
ad 2. if your application don't want the android filtering behaviour, and you can filter it yourself better, then this would be better for your app.
Example: (is for ios, but may apply here too:) if I drive with my car to a traffic signal, and do a harsh breaking, then ios still shows 5 km/h speed, although I am standing still. This I call unwanted filtering.
This has all nothing to do with battery: if you get the location via message or if you query it is the same from battery point of view. It smore a software design issue: (events vs. polling)
A difference would only be if GPS is disabled, but disabling GPS makes only sense if it can be disabled for long time.
I'm implementing an app that gets your location when you open it. It only gets it when the activity is created, so I don't need a LocationListener. I'm testing it in two real devices.
First I try to get the location using GPS_PROVIDER. If the result is NULL, I use NETWORK_PROVIDER. Since I'm testing it inside a building is to be expected that I won't be able to get the location using the GPS provider.
In one of the devices the location using GPS_PROVIDER is NULL, and the NETWORK_PROVIDER returns the correct location. But in the other device the location using GPS_PROVIDER is not NULL, but it's wrong (it's in a different city than the one I'm currently am!). This is the code I'm using:
private void getPosition() {
locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
myloc = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(myloc == null)
myloc = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(myloc != null){
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
try{
List<Address> addresses = geoCoder.getFromLocation(myloc.getLatitude(), myloc.getLongitude(), 1);
if(addresses.size()>0){
String add = "";
for(int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++)
add += addresses.get(0).getAddressLine(i)+"\n";
placeEdit.setText(add);
}
}catch(IOException e){
e.printStackTrace();
}
}
}
How can I know the location returned by the GPS provider is wrong? Should I look the network provider first and if it's null use the gps? This app is supposed to be used outside, so I'd like to use the gps first since it's more accurate.
Thanks!
As state in Android Documentation
getLastKnownLocation(String provider) Returns a Location
indicating the data from the last known location fix obtained from the
given provider.
So when your device obtained position 2h earlier and in the meantime never get fresh fix, Location object return that old position. I suggest you to use LocationListener but with thread that will stop listening after some period of time - this approach prevent device from long fix-searching in case of bad view to satellites or when you are inside a building. If LocationListener obtain position use it, if not - use NETWORK_PROVIDER.
I am developing an application in android and I want to get the latitude and longitude of the android mobile. My code for getting latitude and longitude is giving values after some time. And sometimes, it doesn't give values at all. Can anyone help me what can be done!
You need to add this code for getting te current location. make sure you give all the permissions
Location Manager location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location!=null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
Please used last know location from your location service provider if you not get latest because
When your application is not running at that time some other application used location manager to get current location.
then once you start your application with location manager,what happen location manager basically take some time to prepare to send current location so at that time you have to get last know location from location provider,for that you have to design service in such way.
once the location manager is stable then used those location.
this is best way.
Thank you
Bhavdip
One quicker way would be to get the last known location getLastKnownLocation()
and check if the time of this location is not far location.getTime(). Or use it until you get the real location.
Another tip is to use both GPS_PROVIDER and NETWORK_PROVIDER so your code will be like this :
LocationManager locManager;
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
/*call both providers , the quickest one will call the listener and in the listener you remove the locationUpdates*/
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0 ,0 , locationListener);
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0 ,0 , locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
/*check both providers even for lastKnownLocation*/
if (location == null)
{
location = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if(location != null) {
String lat = String.valueOf(location.getLatitude());
v1.setText(lat);
String longi = String.valueOf(location.getLatitude());
v2.setText(longi);
}
this is a simple example, a more elaborate solution would compare the newest lastKnownLocation between providers.
I'm working on GPS in android and I want to show the number of Satellite available at that time for current location and I am getting 3 at all the time in my app while in other app they showing 6 to 9 at same location.I don't know what is the problem.
I am able to get Lat & Long current location.
I'm getting no. of satellite from locationManager.getAllProviders().size() in LocationListener
I also tried
int satellite = 0;
GpsStatus status = locationManager.getGpsStatus(null);
Iterable<GpsSatellite> sat = status.getSatellites();
int i=0;
while (sat.iterator().hasNext())
{
GpsSatellite gpsSatellite=(GpsSatellite)sats.iterator().next();
if(gpsSatellite.usedInFix())
{
satellite++;
}
}
but it showing me 0;
please help me.
Thanks in advanced.
You can check out the GpsStatus class methods.
You can use getSatellies() method to get a list of satellites. It is an iterable so you can traverse it and get the number of satellites.