My app collects locations with a foreground service, and it has been working well up through Android 11. With the Android 12 beta, with all permissions that work well for previous versions granted, I'm getting very few locations, well below my update interval settings, sometimes not for several minutes at a time.
Are there some Android 12 changes for running apps with a foreground service, with the LocationManager, or anything else that might affect this?
Edit: Tried mock locations; those come in fine. Also tried adding
android:foregroundServiceType="location"
... which didn't help. I've thought about switching to the Fused Location Provider API, but I've read that doesn't help to get more locations, just the opposite.
My next step is to use the "gps" location provider with the LocationManager; my guess is that will get more locations, but my app has been handling the types of locations from the "fused" provider, so I'd really like a better option.
Using FusedLocationProviderClient instead of LocationManager for Android 12 worked; it looks like using the "fused" provider with LocationManger.requestLocationUpdates with Android 12 will no longer cause new locations to be collected.
Related
The FusedLocation API is newer than LocationManager API, but it is not clear to me when to use one vs the other. I want to monitor location changes even when the user is not running the app.
I found this nice example using the LocationManager but this is from 2011. Is this information still relevant?
The FusedLocation API examples show how to configure a LocationRequest for continuous location updates in your Activity. My question is, how would you use it to monitor location changes when your Activity is not running?
I've seen other examples that use Alarm Manager, but this is basically polling and seems like overkill and might drain the battery (but maybe I am wrong?).
I have referred many questions on this topic, but it seems some of my requirements are missing:
I want to get the GPS location at ~0.0001 accuracy
Don't want to use internet; Though GSM/CDMA network is ok
Should be obtained programmatically when the app starts
Should be quicker, say within a minute (like iPhone, which probably works in Airplane mode as well!)
The code should work in most of the devices
The phone may switch-on/off anytime and travel any distance
Is there any way to get just the co-ordinates with above mentioned requirements? Any sample code snippet will be much appreciated.
Checking various apps like "Locate Me", "Maverick", which claim to show offline locations. But in various scenarios without internet, they don't give track the location (in India).
I have referred plenty of old/new questions inside/outside SO. Below are few:
Is it possible to have the gps location while offline with the nexus
7?
Does GPS require
Internet?
How to get current exact location in android without internet
connection?
[Note: I am asking this question on behalf of my Android team and will be happy to clarify the details if asked for. Should you feel that this post belongs to Android.Stackexchange, then kindly move it.]
1. I want to get the GPS location at ~0.0001 accuracy
You can listen only to GPS provider and discard a location when it doesn't have the minimun accuracy you want:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 5, myLocationListener); // "myLocationListener" must be an object from a class that implements LocationListener
// "myLocationListener" implementation of LocationListener.onLocationChanged
public void onLocationChanged(Location location)
{
int MIN_ACCURACY = 5; // in metters
if ((!location.hasAccuracy()) || (location.getAccuracy() > MIN_ACCURACY))
{
// discard this location and keep listening to new location readings
}
else
{
// that's a good reading!
// do somethings you want... blah, blah, blah...
// stop updates when you get the location to preserve users' battery.
locationManager.removeUpdates(myLocationListener);
}
}
2. Don't want to use internet; Though GSM/CDMA network is ok
Yes, GPS works totally off-line. Android can make use of internet ONLY to update A-GPS data cache and provide faster reads in cold-start updates.
3. Should be obtained programmatically when the app starts
Then call item locationManager.requestLocationUpdates on mainActivity's onCreate event.
4. Should be quicker, say within a minute (like iPhone, which probably
works in Airplane mode as well!)
Keep in mind that iPhone works with "high quality hardware". Android can be run on crappy devices. So it'll depend of:
The device's hardware quality;
The number of satellites that are visible in the sky at that moment;
The age of almanac and ephemeris data on gps cache;
GPS can fail to read satellites because user is inside a building or something.
5. The code should work in most of the devices
What is the oldest Android's API you want it to run?
6. The phone may switch-on/off anytime and travel any distance
I didn't get it. What is your concern about this?
------------------------------------------------------------------------------
Update 1:
"...I would like to use Android 4.0 and above..."
I've tested GPS features from Android 2.3 to 5.0 devices. Everything runs pretty fine on all of them.
"...I have observed that 1 geo-coordinates based demo app which was working in other devices, din't work in my LGG3 with Android 5.0. Any idea on that?..."
Did you check GPS permissions on Android settings? (Maybe it's disabled) Or can be a hardware issue? Did you try in another similar device?
"...Suppose the GPS is showing correct location in New York,
I switch off the phone and then switch on after reaching to London,
then will it still show correct location (without internet)?..."
Sounds you're confusing things: reading a GPS location is one thing. Showing that location into a MAP is another different thing!
You don't need to be connected to the internet to do GPS location reading. But, if you want to show that location into a MAP, probably you're gonna need internet (to load map resources, etc.).
If you nedd to stay collecting GPS locations periodically (let's say, from 10 to 10 minutes), then it will be better to use AlarmManager to schedule a timer that will "finger" your app and say "hey, time to make a GPS reading!".
"...Also what is your opinion about the latest Fused API?..."
I've tested it and used it for a while, but I gave it up. It needs that Google Play Services be installed to work (not a problem, most users have it on their devices). But if you need ACCURACY (as I do), it will not work. It uses "fused sensors" (accelerometer, gps, wifi, compass, etc...) to try to get user location with minimum power possibile. Sometimes, it says you're 10 miles away from where you're really is. I couldn't make it work fine to keep the "path" where user has been. But it really saves battery.
Suggestion is to use Google Location Services
It takes the best possible and accurate location as accurate as it can at current moment. It automatically (with configuration of course) takes best current accuracy too - whatever is available GPS, network, internet, GSM/CDMA/LTE... It also cashes last known location so, basically, you know it every moment - the best what you can.
Of course you have to realize that each service provides its own accuracy and in it's own time. Look, for example, GPS Test App on Android and see how accuracy increases with time and used satellites.
Also Location Services is good for you because it simply provides coordinates - just as you asked and hides a lot of work to determine what real service to use based on time and accuracy. However, of course, if none of the services on your particular device and location can give you required accuracy then there is no way to get it. That's why services also provide accuracy measurement.
Here is another link
Use fused location API provided by Android SDK.Implement fused location in a Service and call it in your application MainActivity.
I newbie in location and trying make service to show my current location and another one location saved previously. And what the difference of using LocationListener vs LocationClient?
The LocationListener connects to the LocationManager and retrieves your location. This worked and works fine.
The LocationClient is a new way to implement this while some of the rest gets deprecated. It features more functions.
Both methods actually works.
Location Manager was introduced in Android SDK and can be used as a feature of android.
Location Client is something that's part of Google Play SDK and is introduced in the recent Google IO 2013.
You can understand that since LocationClient is the latest, it is more efficient in getting the location with minimal energy(battery drain) with greater accuracy.
Reasons to use LOCATIONCLIENT because:
The location update behavior is very abnormal and wont work as you expect. i.e. The location updates get stuck when switching networks. (It keeps giving you some old location)
The location client wont work on modified android versions of the android OS, as it requires Google play services.
Location Client might be good on the battery of the phone but it won't be good with giving you timely accurate location updates.
I recommend good old Location Manager as I don't find location client reliable at all.
Note : There is no point of saving battery if you are not even getting your current location in a location based application.
I am developing an android application wherein I need the user location updates pretty frequently. Say 2 times a minute.
Earlier I had been using Google Play Service's "Fused location service" but the location updates were not received as requested.
The location updates got stuck for sometime, the interval between updates jumped to 10min or so.Sometimes even if I put my priority to "PRIORITY_HIGH_ACCURACY" the same happened.
I then went back to the old "Location Manager" and when I used the "NETWORK_PROVIDER", I noticed that the location updates got stuck due to this provider. Also the GPS does not get activated immediately, it takes some time. I am trying to build my custom fused location provider. How can I efficiently switch between providers, without getting lags on location updates.
I want to know what are the best practices for getting location updates regularly, all the time, be it either NW, GPS or both. Like it should work for an application where location updates getting stuck cannot be afforded.
Battery drain is not an issue for me right now.I am aware of all the supporting docs that Google provides regarding location access.
Any help would be much appreciated.
Thankyou !
FusedLocationProvider really is the best option for obtaining locations at the moment, because it uses a lot more than just GPS or Network data to obtain location fixes. I have experienced issues regarding intervals being missed as well, but ultimately this is something down to luck depending on availability of GPS, Network, etc. etc.
My favourite usage of FusedLocationProvider so far is in conjunction with the AlarmManager class: Basically, the idea is to start location tracking at intervals specified by the Alarm Manager (this can be set to every 30 seconds such as in your case). Once the interval is hit, the location provider is to obtain a location fix as soon as possible (so in the setInterval method or whatever it's called, the parameter is a 0). This way, you can avoid having to wait another 30 seconds for a new location, instead having the location tracker attempt to provide a location as soon as possible after the interval specified by the Alarm Manager is hit.
By the way, when making custom location tracking wrappers, be careful of using the .getLastKnownLocation() method as it only uses cached locations - you could end up sending the same location to the user every 30 seconds.
Good luck!
What is the difference between LocationClient and LocationManager.
What is the pros and cons between them (like battery, accuracy)?
Which is better to use?
Location Manager was introduced in Android SDK and can be used as a feature of android.
Location Client is something that's part of Google Play SDK and is introduced in the recent Google IO 2013.
One can understand that since Location Client is the latest, it is more efficient in getting the location with minimal energy(battery drain) with greater accuracy.
UPDATE: LocationClient is deprecated. You have to use GoogleApiClient. An example of it can be found here.
Google Play Services Team has cleaned up their code and moved LocationClient functionality into GoogleApiClient.
Tutorial for the same is available in
http://developer.android.com/training/location/retrieve-current.html
On following link you can find IO talk about this subject
http://www.youtube.com/watch?v=Bte_GHuxUGc
UPDATE AGAIN
GoogleApiClient has been deprecated again, you have to use GoogleApi based APIs instead.
I have been developing a location based application in android and I seriously NOT recommend using the LOCATION CLIENT in any case. Reasons :
The location update behavior is very abnormal and wont work as you expect. i.e. The location updates get stuck when switching networks. (It keeps giving you some old location)
The location client wont work on modified android versions of the android OS, as it requires Google play services.
With my experience, Location Client might be good on the battery of the phone but it won't be good with giving you timely accurate location updates.
I recommend good old Location Manager as I don't find location client reliable at all.
P.S. : There is no point of saving battery if you are not even getting your current location in a location based application.
EDIT:
If you know the implementation of LocationManager and LocationClient (both are available in documentation), you can create your own LocationClient-like wrapper (with callbacks and stuff), which will be working on LocationManager but with custom tweakable properties.
EDIT 2:
Please find the LocationManager Wrapper class here, which provides timely location updates:
https://github.com/rahulsh12/LocationManagerWrapper
I have worked on a tracking app and my experience is that LocationManager is better than LocationClient. LocationClient does not provide any way to specify that you want location updates from GPS only. All it allows is to specify "high accuracy". This works for most part but every now and then you get a location update which is hundreds of meters off BUT with a specified accuracy of a few meters. There is no way to know you got an unusable sample. With LocationManager if you specify GPS_PROVIDER you can be assured that you are never going to get wildly inaccurate samples. Working well for us.
Coming from someone who switched over to Google Play Services a while ago, i can give you some experiences:
I have an app, about 2,5 years old, that uses location services extensively. From the outset, of course, we used the LocationManager since that's what was available on the Android platform.
We had a pretty bad experience with Location Services on Android compared to IOS. It was buggy, unreliable, and gave less precise locations than than our IOS app, plus that it drained more battery. It was a drag.
Therefor, when Google unveiled the new API in june this summer, we jumped at it. It is way better. A couple of things:
It is quicker and more reliable.
It is less buggy. As an example, in the old API we could sometimes get an "old" fix with a new timestamp. This never happens anymore. There's more but it would be an even more lengthy post.
It definitely drains less battery. For example, when you had a map view open, the GPS ran all the time, and the GPS icon was visible. This is not the case with the new one. This made users wonder what was going on. This is nolonger as big an issue.
So, when it comes to the location output and work, everything is better. But there are some downsides:
You have to have Google Play Services installed, meaning it wont work on any "non-google-approved" phone models, and in some instances you'll have to tell users they need to install it.
The API itself is more complex IMO, in part due to point 1. In addition to the "regular" callbacks i.e. waiting for location fixes etc. You now have a process that takes part before you can get started where you have to check that playservices is available, and "connect" the locationclient. This is extra code and a bit more complex to grasp. More faulty conditions to take into account in the code too (if you can be bothered...)
Google play services itself requires at least 2.2 so it won't work for older devices than that. We had to tell some clients they had to upgrade...
Hope this helps.