I am developing an app which can record user's location througout the day so app can find out the approx lifestyle of user. app has to collect data in the background at some interval so i need a best strategy to invoke a location update request to LocationManager of android. But it must be optimized in terms of battery and balanced in terms of accuracy.
Right now the flow in my mind is,
iterate through the location providers, give higher priority to NETWORK (as it consumes less power), o this for each,
get the last known location
get the current loction
chek if current is better than last
if yes make this the best estimate, otherwise get location from other provider
i know two parameters which can decide when to invoke location update request,
minimum interval
minimum distance
first i would give them some default value but these must be updated later by using the location history of user and considering other factors in mind like
reduce the frequency of update request if battery is < 75% and further reduce it when
battery is < 50%
increase frequency of update request when user is moving fast (Activity Recognition Class
from google location services can help here)
if we predict the time windows in which user does not move (from history), decrease the
frquency of location updates
use GPS minimal time because it consumes more battery
So these are the pieces that came to my mind but it looks like a mess right now because it is not well structured. So if somebody can help me to add something more in this or can suggest some better strategy (battery must be optimized) i would be very thankful and it was long so please control your emotions if you think i have wasted your time. Thanks
In order to get a good accuracy, Google provides an algorithm that provides, in my opinion, good results. You can find it there : reference
GPS take so time to have a fix, I would say about a minutes (depends on the device).
I would suggest you to look at the Passive Mode, which allows you to receive position without making a fix by using other applications requests.
passive: 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.
gps tutorial
Hope it helps !
Related
I'm building an app that should be able to report the users exact location. There is only a need for a single location, i.e. I don't need to track the device continuously.
I want the location to be as accurate as possible, and it's okay to wait a short while for the location to be determined (max 1-2 minutes).
I've been looking at FusedLocationProviderClient.getLastLocation(), but since I want the location to be as accurate and updated as possible it doesn't fit my needs.
So I started looking at using FusedLocationProviderClient.requestLocationUpdates() instead, and it seems like a better choice.
But I'm not sure how to best configure my LocationRequest to get as good accuracy as possible. For instance, would it be better to use setNumUpdates() so that I only receive a single update and use that as my location, or should I receive multiple updates in hopes of getting better accuracy (GPS locking to more satellites for example)? I'm thinking that if I use the second approach, I could look at the value of getAccuracy() from each location update and only keep the one with the highest accuracy. The downside is that if the device is moving and I keep receiving updates for a minute or so, the first location could have the highest accuracy, but since it's a minute old it's not accurate any more.
As stated above, I need just a single highly accurate location and it's okay for the app to wait 1-2 minutes for it if needed. What would be the best approach in this kind of scenario?
First, make sure the accurate location is turned on. look at Settings.Secure.LOCATION_MODE_HIGH_ACCURACY It has a noticeable advantage over only using GPS. Then listen for the location for a while and calculate the result you get to find out the best location. You can also detect if the user is moving if the number differs a lot or by using Activity Recognition API. It shouldn't be very hard to write this calculate function to get the best result.
I'm not sure about this but I really don't think waiting more than a few seconds gives you an advantage. to be sure you can simply alter this time and watch the result.
You might want to use LocationManager. In my experience FusedLocation will indeed appear to lock faster but may not be as accurate overall, or at least for a while. I have an app that also requires pretty accurate coordinates. My default is to use a LocationManager based approach but users can switch to a FusedLocation provider if they want faster locking (like when indoors).
This is a good overview https://developer.android.com/guide/topics/location/strategies
For the provider when requesting updates I'd use LocationManager.GPS_PROVIDER. It will take longer to lock since it will wait for satellites and not use Wifi or other towers. But you said that's OK. Something along these lines
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, YourLocationListener);
Once you start getting location updates via your listener's onLocationChanged() you can start to inspect the location for accuracy, movement from last location change, etc. to try and evaluate if the GPS receiver is still settling in on a location. Once you are satisfied with the quality of the fix you can stop receiving location updates (locationManager.removeUpdates(YourLocationListener)) and then run your logic that needs the location. The link I provided has good info about this too.
I'm developing an android app fully based on user location, so I would like to receive the coordinates as frequently as possible. For this case I decided to create a service that will run in the background (looping) and use user GPS and NETWORK providers every 10-15 seconds and after it received a fix, turn them off. Is it a good practice?
When you are convinced that you need user accurate location and you need it to be update then you need it. However you can take a look at this answer to understand preferred manner to implement it (of course with a little change)
And please consider using Google Fused Location :
The Google Location Services API, part of Google Play Services, provides a more powerful, high-level framework that automatically handles location providers, user movement, and location accuracy. It also handles location update scheduling based on power consumption parameters you provide. In most cases, you’ll get better battery performance, as well as more appropriate accuracy, by using the Location Services API.
Refrence
There may be similar questions regarding this topic,But I need your thoughts and suggestions on some specific requirement.
Here is my need -
We are developing one app which tracks User's trip.
The app will start collecting the location of that user in background,When user 'Starts' his trip from App.Background Service will be fetching locations on the basis of user's movement in specific time duration.
When User 'Stops' his trip from App,We are calculating distance traveled by user with help of all recorded locations(With Google Distance calculating API).
The App works fine in ideal case.
But main challenge is -
In some scenarios,We are not able to fetch exact and precise location of User. Scenarios affecting is - No internet,Data plan with 2g/3g,some specific areas where GPS is not returning accurate data etc.
Incorrect data of lat-long causes incorrect Trip distance and route.Which is main problem with the App.
Please,any one can suggest the best alternative/Suggestion for this?
P.S. - We have tried GPS,Network,FusedLocationProvider.
EDIT 2 --
We have implemented logic on basis of accuracy and distances.Got nearer points. And just came across one useful api from Google that corrects some location points which are distracted from actual Roads. Posting here for reference of others...
Snap to Roads Api from Google
this is a complicated topic.
One consideration you have to take. Android Oreo limits background services and that what you want to achieve won't work.
I would do is this (and it is the recommendation from Google)
When someone starts the trip (the user is aware of it), you must launch a on going notification with a foreground service , don't rely on background services anymore. Check the feature "Start Activity" in Google Fit App.
As for not having signal, or accurate GPS, well... it is a geographical problem!, there is nothing you could do. Or, maybe you can, using the LocationProvider.
FusedLocationProvider is fused within every app that requests locations updates.
Read this out, and see if that helps you.
https://developer.android.com/guide/topics/location/strategies.html
Try to mix GPS and Accelerometer
If you detect that GPS stopped working, turn on accelerometer. If GPS is turned on again, calculate distance again with it. This way you can have route with GPS parts and accelerometer ones. The bigger GPS parts, the more accurate data will be
How to get more accuracy by GPS_PROVIDER
Basically if the accuracy of a location isn't acceptable throw it away. The next one will be better.
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'm creating an app wherein I'm need to perform an action when I'm within a certain radius of a location. But I don't want to be continuously polling the location because that'll drain the battery.
I thought about just putting an option for the user to specify how often to query the location. However, I'm concerned that if the user sets it too long, then my app will miss performing the action when it's near the location.
I in one Google IO session that Pay With Square had an auto tab feature, I'm not sure if they're constantly polling the location, have setting for the delay between querying the location or a third option that's efficient without draining the battery.
I would like to ask for suggestions on how to approach this.
Thanks in advance.
It looks like your question actually is: "how can I get an accurate position measurement while saving the battery of my device?"
There are mainly two ways to save battery AND have a good positioning:
Do not use GPS (that is a real battery hog)
Set a large interval between poll actions
You can get a quite good positioning (from 40 to 150m radius, that is better than GPS in many cases) using only the wi-fi and phone cell data. Just select "ACCURACY_COARSE", "ACCURACY_LOW" and/or "POWER_LOW" as a provider selection criteria in your code.
See the following links at Google Developer's web site:
Location Strategies
Location and Maps
LocationManager
And in particular these two:
getProviders
Criteria
You can select/set a battery-saving poll interval on the basis of the measured speed of the user. If the user is walking (less than 5 km/hour), you can use a 30 - 60 seconds interval without any risk to miss your alert. If the user is traveling by car (more than 50 km/hour) you will have to set a 1 - 10 second interval. Consider that location space accuracy is usually quite bad (100 m or so) so it does make very little sense to try to "cath" the point with a very high time (speed) accuracy.
Have a look at Google documentation for this, as well.
In any case, Google explicitly suggests to NOT try to save battery using your own code and rely on the getProviders criteria for this.