I have created application that gets a relevant lat and long and updates in a database. The problem is that when I under a roof like house or mall... I keep getting the GPS searching ICON on my app.
I am using a button to trigger the Mylocation() and it's listener.
The button has the following:
locationListener = new MyLocationListener();
location.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, locationListener);
and under the mylocationlistener method I have
private class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
try {
Thread.sleep(1000);
Toast.makeText(getBaseContext(),"Location: Lat:" + loc.getLatitude() + " Lng:" + loc.getLongitude(),Toast.LENGTH_SHORT).show();
location.removeUpdates(locationListener);
location = null;
finish();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
I get the value toasted properly without any problem and app is finished an GPS icon goes away but when I am inside the roof and GPS icon in top keeps searching for GPS. The icon doesn't go away.
How do I fix this? Do I need to put a condition if Gps signal is good start the GPS if not just message GPS signal not good. if so how?
Thanks!
As described in this question How to measure GPS signal strength on Android,
So assuming that you really mean signal strength, you can get the GpsStatus via LocationManager.getGpsStatus(), and that gives you a list of satellites via getSatellites(), and each one of those has a signal-to-noise ratio (getSnr())
You could consider using the network location service as well as or instead of GPS. You could also consider adding a timeout.
Related
OLD QUESTION:
I'm trying to get my device's location coordinates and I've followed all the steps that I've found in multiple areas while researching. I've set up a LocationManager and used the requestLocationUpdates function that is tied to a LocationListener. However, the LocationListener does not respond. I've tried debugging as well as walking around outside in order for the onChangedLocation function to execute but nothing happens. In debugging the requestLocationUpdates function for my LocationManager is executed but the LocationListener is never executed.
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
textView = (TextView) findViewById(R.id.textView);
textView2 = (TextView) findViewById(R.id.textView2);
locationListener = new myLocationListener();
textView.setText("Longitude", TextView.BufferType.NORMAL);
textView2.setText("Latitude", TextView.BufferType.NORMAL);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, locationListener);
requestLocationUpdates
Above is the use of the requestLocationUpdates function.
private class myLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
//Log.e("Latitude: ", "" + location.getLatitude());
//Log.e("Longitude: ", "" + location.getLongitude());
if(location != null)
{
textView.setText(Double.toString(location.getLongitude()), TextView.BufferType.NORMAL);
textView2.setText(Double.toString(location.getLatitude()), TextView.BufferType.NORMAL);
}
else
{
textView.setText("No Location", TextView.BufferType.NORMAL);
textView2.setText("No Location", TextView.BufferType.NORMAL);
}
Toast.makeText(getApplicationContext(),"onLocationChanged Success",Toast.LENGTH_LONG).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
}
myLocationListener
This is myLocationListener that implements LocationListener. I've added a little bit of extra code for testing purposes. The toast would never pop up so it appears as though this code is never executed. If anyone could help me out with this I would really appreciate it.
Thank you!
NEW QUESTION:
After continuing on developing in this page while waiting for a response I noticed that it takes about a minute for the location services to actually begin working. So, now my question is: how do I overcome the obstacle of a user having to wait to use the app? I've seen apps that use location based content and it does not take that long. I know that there is the getLastKnownLocation function but what if a user travels 50 miles before opening the app again? Any help on this would be appreciated. Thank you!
Each device which makes location request for gps, has to wait until gps hardware become warm. The wait time changes by device and where you stay. If you are inside a building, this time could take 1 minute or more.
To avoid wait, you can use getLastKnownLocation method, if returns a cached location, check location's date via getTime method. Determine yourself, is it old location by your scenario ?
if it's too old location, you have to make location request and wait.
I'm trying to find a way to turn off the GPS immidietly in case a good enough location was found, while still having a time limit to "give up".
I tried to do this with the following strategy:
start checking for locations, as soon as a location that has an accuracy lower than the maximum tolerated, pass it to the next function for processing and stop looking for updates.
Also, to save battery life, if such location could not be found in 30 seconds, stop looking for location updates without passing a value (basically give up, and hope to better luck next time).
To count the 30 seconds, I'm using a handler. But as soon as I write the line locationManager.removeUpdates(locationListener); in the handler, the locationListener in the parenteses in both lines (the one in the handler and the one in the listener) turns red and reports an error: The local variable locationListener may not have been initialized
Here is my code:
private void checkProximity() {
final LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
//start tracking location
final LocationListener locationListener = new LocationListener() {
...
#Override
public void onLocationChanged(Location location) {
//if new accuracy is better than the best estimate - update the best estimate
if(location.getAccuracy() < MAXIMUM_TOLERATED_ACCURACY) {
//forward location to scanProximity and end the location search
scanProximity(location);
locationManager.removeUpdates(locationListener); //FIRST LINE (see below)
}
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
500, 0, locationListener);
Handler h = new Handler();
int delay = 30 * SECOND;
Runnable removeListener = new Runnable() {
#Override
public void run() {
//if this code is reached - the maximum tolerated accuracy was not met in the period time
//extended to find a location
//TODO stop the location manager and return without forwarding a value
locationManager.removeUpdates(locationListener); //as soon as I write this line, the FIRST LINE and this line turns red.
}
};
h.postDelayed(removeListener, delay);
}
Is there anyway I can do this differently so I won't get an error?
I recommend you use Little Fluffy Location Library to work with GPS locations. Check out the examples codes and see which makes you more easy the solution to your problem , this is a beautiful way.
I want to know if there is a way in Android (GingerBread) to know if at the moment the GPS is doing something or not. Let me be a bit more clear: I basically want to call some method or api that will tell me wheter the GPS is:
1)Fixed (GPS icon in statusbar on)
2)Searching for fix (GPS icon on statusbar blinking)
3)Inactive (No app is using location services at the moment, no icon on statusbar)
Now: I know that you can use a LocationListener to be notified of such changes BUT this is not good for me because I don't want my code to remain running waiting waiting for events, my code runs periodically at scheduled times, does something and then terminates, so I need a way to check the status of the GPS service in that precise moment, rather than wait for notifications of when it changes.
After doing lot of testing on GPS, finally I found the solution. When android app calls location manager and GPS starts searching, one event is triggered and also when gps is locked another event is triggered. Following code shows how to do this.
locationManager = (LocationManager)mContext.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
if (locationManager != null) {
// Register GPSStatus listener for events
locationManager.addGpsStatusListener(mGPSStatusListener);
gpslocationListener = new LocationListener() {
public void onLocationChanged(Location loc) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES_GPS, MIN_DISTANCE_CHANGE_FOR_UPDATES_GPS,
gpslocationListener);
}
}
/*
* This is GPSListener function invoked when various events occurs like
* GPS started, GPS stopped, GPS locked
*/
public Listener mGPSStatusListener = new GpsStatus.Listener() {
public void onGpsStatusChanged(int event) {
switch(event) {
case GpsStatus.GPS_EVENT_STARTED:
Toast.makeText(mContext, "GPS_SEARCHING", Toast.LENGTH_SHORT).show();
System.out.println("TAG - GPS searching: ");
break;
case GpsStatus.GPS_EVENT_STOPPED:
System.out.println("TAG - GPS Stopped");
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
/*
* GPS_EVENT_FIRST_FIX Event is called when GPS is locked
*/
Toast.makeText(mContext, "GPS_LOCKED", Toast.LENGTH_SHORT).show();
Location gpslocation = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(gpslocation != null) {
System.out.println("GPS Info:"+gpslocation.getLatitude()+":"+gpslocation.getLongitude());
/*
* Removing the GPS status listener once GPS is locked
*/
locationManager.removeGpsStatusListener(mGPSStatusListener);
}
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
// System.out.println("TAG - GPS_EVENT_SATELLITE_STATUS");
break;
}
}
};
It is better to put GPS code in and as service to get GPS location information.
Each time if you call GPS function, GPSStatus listener is registered. GPS_SEARCHING toast comes only once when GPS is started to search and GPS_LOCKED toast displays when GPS is locked. If we call GPS function again, GPS_EVENT_FIRST_FIX event is triggered if it is locked(displays GPS_LOCKED toast) and if GPS is already started to search it won't display GPS_SEARCHING toast(i.e GPS_STARTED event won't trigger). After GPS_EVENT_FIRST_FIX event is triggered i'm removing the GPSstatus listener updates.
When GPS_EVENT_FIRST_FIX event is triggered, its better to call gpslastknownlocation() function to get fresh latest GPS fix.(Its better to look into Android developers site for more info).
I hope this will help others....
Unfortunately, there's no easy way to get the "current state" of the GPS in Android. Like others have pointed out, your best bet is to register for the onGpsStatusChanged() event and track the state.
If you are feeling adventurous, you can call call $ dumpsys location from an adb shell to get the state of the gps provider. You usually call $ adb shell from your desktop, but you can compile a native android shell app, and call an exec() from inside the shell to get the dumpsys output directly on the phone.
Here are snippets of my code:
private class NoGpsLock implements Runnable {
public void run() {
if (gps == null) {
Toast toast = Toast.makeText(getApplicationContext(), "Unable to find GPS lock", Toast.LENGTH_LONG);
toast.show();
if (locManager != null) {
locManager.removeUpdates(locListener);
}
}
}
}
Called by
try {
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DIST, locListener);
} catch (Exception ex) {
}
Handler gpsHandler = new Handler();
gpsHandler.postDelayed(new NoGpsLock(), 15000); //15seconds
From what I understand, removeUpdates() is supposed to stop the GPS receiving updates. I tried this on the emulator and on 2 devices; on the emulator, it does stop the app from receiving further location changes. However, on the actual devices, the icon for "Receiving location data from GPS" keeps showing up and drains the battery (which I assume indicates that the app/phone keeps on looking for a location and unable to, since I'm indoors). How do I stop the GPS from trying to find a location?
EDIT: I want my app to stop trying to find location after a period of time, and then maybe restart the GPS again later.
removeUpdates(locationListener) is supposed to stop that blinking GPS icon. If it isn't doing that, the best suggestion I can offer is that maybe there are there are other listener instances still registered with your locationManager? A forgotten for-loop could have attached other listener instances. As a brute-force developer I'd do removeUpdates() multiple times to see if that has any effect.
i'm working on app, which must get latitude and longitude. in my case requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener) is not in option. why? because i must get location just when user do something that location is needed (let's say he hits button). and i need location exactly on the time, when button is hit. in requestLocationUpdates, we can set minTime-if i set this let's say on 30000 the location at the "button hit time" won't be as good as i want. of the same reason minDistance is also not as good as i want. if i understant function requestLocationUpdates correct-when minTime and minDistance are set to 0, location is updating all the time. please correct me if i'm wrong. app is for company that i'm working at and that app will be used through the day and night. so if app will check for location updates all the time, battery would be often empty. that's why i need location just at the time, that button is hit. users are not having access to internet and gps. so i must use NETWORK_PROVIDER
I also have problems with getting location after reboot device. it doesnt work until i run google maps. users wont have avalible this either, so what function do google maps on android use to get location after reboot?
at the moment i use this code:
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mlocListener);
mlocManager.removeUpdates(mlocListener);
public class MyLocationListener implements LocationListener{
#Override
public void onLocationChanged(Location loc){
latitude=loc.getLatitude();
longitude=loc.getLongitude();
Text = "My current location is: \n" + "Latitud = " + loc.getLatitude() + "\nLongitud = " + loc.getLongitude();
Toast.makeText( getApplicationContext(),Text,Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider){}
#Override
public void onProviderEnabled(String provider){}
#Override
public void onStatusChanged(String provider, int status, Bundle extras){}
}
code is from here
but this code is not working right. if i press "get location button" the Toast is shown and location is correct. but then if i press button several times, it does nothing. -but after 5 minutes Toast is shown like hundred times... why is that?
You are immediately calling removeUpdates after the requestLocationUpdates. So, the listener is never registered. Call the removeUpdates in the onLocationChanged method.