I have an operational Android app which reports users location within a background service. I want to integrate a feature which will notify the user when GPS signal has been lost.
Our current implementation to commence location updates is:
mLocationListener = LocationListener(LocationManager.GPS_PROVIDER, gpsDeviceCallback)
if (handlerThread?.isAlive == true) {
handlerThread?.quit()
}
handlerThread = HandlerThread("GpsLocationHandler")
handlerThread!!.start()
mLocationManager?.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE.toFloat(),
mLocationListener, handlerThread!!.looper)
with LOCATION_INTERVAL set to 1000 ms and LOCATION_DISTANCE set to 10m.
We get the expected onLocationChanged callbacks under normal operation. However, I would appreciate advice on how to detect a situation where there is a loss of GPS or handset cannot obtain an adequate GPS signal.
We have implemented a solution where we run a time task and determine if onLocationChanged is called during the timer period. The problem with this solution is that if the user handset is stationary during this time then no onLocationChanged callbacks will happen. So this approach will not work as a means of detecting no\inadequate GPS signal.
The user of onStatusChanged as a method of LocationListener is now deprecated so this is not an option either.
Is there some standard solution to this problem ? Perhaps some method which could be called in the case where no onLocationChanged callbacks happen when our check timer expires to test current GPS status?
Thanks!
you can check the current connected satellites and approximate the accuracy see :https://stackoverflow.com/a/10589949
Related
I have an app that tracks user location continously. Now, this works as follows:
I have foreground service that schedules repeating alarm via AlarmManager. Alarm Receiver in onReceive method starts service again. Inside service Im receiving current location from Locator (singleton class that gets location form GP Services). Alarm manager fires alarm once in a 12 minutes, and I want to set repeating time to 1 minute or less. But i`m aware of too frequenlty waking up device - I think it will consump battery very fast.
This foreground service works always.
Are there any other, better way to track location continously?
You can use LocationListener.
google location listner
Checkout answer on this thread: Getting location
In above answer, while creating object for LocationRequest call these two methods, setFastestInterval(long interval) and setInterval(long interval) which will fetch location after some interval.
I asked this question (Why Does Map Marker Lurch Around The Map) yesterday. One thing I noticed today is that for an activity that uses LocationManager, but not a map I get the GPS icon (satalite dish beaming signals up) in the status tray. With the activity that has a map fragment and also uses LocationManager I do not get the GPS icon in the tray. I copied and pasted the location manager code from one activity to the other.
Why would the GPS come on some times and not others?
Greg
It depend on global GPS setting - if it's globally on, using LocationManager in your Activity\Fragment will fire "satellite dish". If GPS is globally switched off - using LocationManager will not fire.
The reason is that GPS is a huge power consumerist, and allowing it to run without clear user decision to switch it on will drain the device battery extremely quickly.
My application uses a progress dialog to let my user know that the location listener is currently searching for their current coordinates as shown:
ProgressDialog searching;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, locationListener);
searching = ProgressDialog.show(this, null, "Gaining GPS posistion...", false,true);
This is great but I want to set a time limit that this can run for. Can i use a simple Thread.Sleep static instance set at - for example - 20 seconds? This will then check if my location object is still null and will then cancel the search?
Can i run both a Location Listener and a thread.sleep concurrently? I have looked at the Oracle notes for Thread.Sleep but I'm still not 100% sure.
Can i use a simple Thread.Sleep static instance set at - for example - 20 seconds?
That would be disastrous. Do not use sleep() on the main application thread in Android, as it freezes your UI for however long your sleep() call is set for.
There are many better ways to get control in your activity in 20 seconds. The lightest-weight solution is to call postDelayed() on one of your widgets, with a Runnable that will execute what you want in 20 seconds.
I have looked at the Oracle notes for Thread.Sleep but I'm still not 100% sure.
Since Oracle has little to do with Android, you are better served reading Android documentation.
I have a program that reads and writes all the sensors values file, but when you turn off the screen stops the listener on the sensors and the record on txt file.
I already tried with the wake lock, but with little success, I want to know if you have ideas or if I have to resort to a wake to keep me always on the monitor, let me know.
thanks
Solved?
Try onResume and LocationListener
You better should use a Service for listening to the sensors. I did so with my Sports Tracker app and ist works fine.
At least the GPS system (LocationManager.requestLocationUpdates) is working with a wakelock when the screen is turned off. I don't know about the other sensors. (you tagged GPS with your question)
How do you improve slow GPS signal acquisition on the Android platform?
I'm testing a simple GPS logger based on this open source code, and although it seems to work, it can take up to 10-15 minutes for it to first acquire a signal and start showing GPS coordinates. However, running the Google Maps app on the same device appears to acquire a signal almost instantly (it's even able to detect which direction I'm facing in realtime), while the GPS logger service still says it can't find a signal.
Why is Google Maps so fast at acquiring a GPS signal, while the standard GPS system service takes forever?
The specific code I have that starts the GPS service is:
private void startLoggerService() {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
2000,
1,
locationListener);
}
There are a couple of things you should be aware of and definitely take into consideration when it comes to using positional data:
Don't rely on just the GPS sensor. Although GPS can potentially give you the most accurate result, it is relatively slow and quite the battery hog. In stead, also request location updates from the network provider: LocationManager.NETWORK_PROVIDER. In most cases this will give a result accurate enough to use in your app (most devices I've played with seem to yield a worst case accuracy of roughly 60~65m), but more importantly: it's much, much faster. Do note that just as with the GPS, users can enable and disable feature themselves in the system settings. For more details, see Using the Location Manager.
Think about how often you need a location update. If possible, prevent continuous updates (that'll drain the battery in no-time) and release the sensors as soon as you've received the data you require. Also, a good practice is to cache the location to some extend - even if it's not completely accurate, users do get feedback immediately. You can potentially combine this with some logic that takes the time stamp into account.
Use the resources that are already available on the Android Developer website. For example, there is a topic on Location Strategies that will be worth reading. Another good resource will be the blog post by Reto Meier and his open source project that implements his Android Protips for Location. If you have the time, also go over his Google I/O 2011 presentation that discusses best-practices for location-based/location-aware Android apps.
On a side note: the realtime indication of what direction you're facing has nothing to do with locations, but comes from either the magnetic field sensor (read: digital compass) or gyroscope. Both deal with the device's orientation, not position.
The 1 in your code means that the provider will only broadcast the location should your device move by 1 meter. Try setting this to 0.
The API documentation states:
"The frequency of notification may be controlled using the minTime and minDistance parameters. If minTime is greater than 0, the LocationManager could potentially rest for minTime milliseconds between location updates to conserve power. If minDistance is greater than 0, a location will only be broadcasted if the device moves by minDistance meters. To obtain notifications as frequently as possible, set both parameters to 0."
If google maps is showing your direction, it must be using a GPS fix. Google maps must be using the most recent gps fix which you can get using Location.getLastKnownLocation. Presumably if that location is not too old Google maps decides it is way better than nothing and shows it to you while you wait for new GPS fixes.
GPS fixes will often come really slowly or not at all when you are indoors. I assume as you develop you are trying to get GPS fixes? You may have to get up and walk outside.
Many phones have fairly lousy gps receivers. Even in clear outdoor sky I own phones which will take MANY minutes to get the first GPS fix. It sucks and its a rip-off, but its true.