I need for my app an service that tracks the phones location all the time. Its used to create a path that the user traveled, will be displayed in the app and should be distinguishable between walking and other means of movement.
The location should be of high accuracy combined with timestamps and speed and saved in an sql lite db for further use in my app.
What is the best way to tackle this problem? I encountered that background services weren't able to get the location often enough. My last resort would be to make it a foreground service but maybe someone has already a solution to this problem. (e.g. is it possible to get the location data google keeps track of in a usable format?)
Thanks in advance!
Edit:
I am sorry that i wsant clear enough.
The problem is that during my research i found out that there were several ways to get the data needed. The location manager and fused locoation.
All of these are limited by how often you are allowed to gain GPS data when the service runs in background, which might reduce the path accuracy. Some solutens were to make it a foreground service so it wont suffer from the same limitations, but that isnt something i want to implement.
To formulate a more precise question: What is the best way to collect accurate(!) GPS location data over a long time using a background service while not draining too much energy? It could also be in batches, as it isnt used in real time but to evaluate later.
Try to just ask specific questions. Otherwise, no one knows how to help or answer you. Since your new on this platform, I'll try my best to answer your question.
First of all. The "data google keeps track of" are from type Location. You can request location updates by using the LocationManager.
Just register for location updates inside your preferred class:
# Get Instance of LocationManager
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
# Create Criteria / What Accuracy of do you need? No Requirement means also very week locations will be used
Criteria gpsCriteria = new Criteria();
gpsCriteria.setAccuracy(Criteria.NO_REQUIREMENT);
gpsCriteria.setAltitudeRequired(false);
gpsCriteria.setBearingAccuracy(Criteria.NO_REQUIREMENT);
gpsCriteria.setCostAllowed(false);
gpsCriteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
// Get the wanted provider
String gpsProvider = locationManager.getBestProvider(gpsCriteria, true);
// Request for Location Updates your Class must implement a LocationListener Every second a location is received
locationManager.requestLocationUpdates(gpsProvider, 1000, 0, this);
Location location = locationManager.getLastKnownLocation(gpsProvider);
In your class, you implement the LocationListener as mentioned above. In onLocationChange, you get Location Updates of the device. I don't know how you want to display the track of the user. But you can get the Latitude and Longitude from this location object. You have also indicators like quality etc.
#Override
public void onLocationChanged(Location location) {
location.getLatitude() ...
}
If you want to track the Location all the time you have to implement a BackgroundService. Your request for location updates in onStartCommand. However, you have to handle DeepSleep and other functions that set the device into sleep. But you can handle this with a WakefulBroadcastReciever and AlarmManager. Yours create an Alarm which sends an Intent to which is received by your receiver, the receiver restarts the service if the service was set Offline. But handle this with care because it drains the battery of the device and I don't recommend it!! Only for some special business usages.
Related
I'm using LocationManager.GPS_PROVIDER to get the current location of the user but it's taking too much time to return the location, should I use the NETWORK_PROVIDER over GPS_PROVIDER ? Or there is something new and better to get the current location of the user to trace a destination route ?.
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 10f, object : LocationListener{...}
It is suggested to use fused location provider. More details here.
Using the GPS_PROVIDER does take a little while to fetch location updates probably because of its accuracy in my opinion. You could also instead of wanting a new location request an older location that's slightly stale (Say for example 2 mins old) and that would be almost ready to use.
I would, however, recommend NOT using Location Manager at all and since it is depreciated and was replaced by a much cleaner and performant Fused Location Provider API. It has support for last location, location updates and it's the currently the method Google recommends.
I have been following this for my application that needs to get current location updates even if 10 steps are walked, or maybe every 2 minutes, but I think time based would be more demanding in terms of battery usage, in the begning documentation says:
your app specifies the required level of accuracy/power consumption and desired update interval, and the device automatically makes the appropriate changes to system settings. These settings are defined by the LocationRequest data object.
what does it mean? accuracy level, and update interval?
After that when its explaining these things they say
To store parameters for requests to the fused location provider, create a LocationRequest. The parameters determine the level of accuracy for location requests.
does it mean that we can get current location update like updated latlng with setInterval()? if so then why we have to use onlocationchangelistener? if requirement has been fulfilled by location request
Thanks
There is exactly two main terms about location, these are
Getting last known location (old location)
Receiving location updates (fresh location)
Understanding the those terms will help in the relation between LocationRequest and it's listener.
Getting last known location
The location api can give the last obtained location for given provider, without location request. This location could be obtained at any time for example 3 - 5 hours ago and by an app(including yours). There is no need to say 'hey provider please give me fresh location', so we don't need LocationRequest object.
Receiving location updates
This is where we need to say 'hey provider please give me fresh location at every 30 seconds with high accuracy'
To define our above request, we need to create LocationRequest object.
To receive result of our request, we need to create listener(receiving process is asynchronous)
This is the relation between LocationRequest and listener.
LocationRequest object is used for two purposes
As mentioned above, to make location request for fused provider
To prompt a dialog to make adequate requirements of location request(for example level of accuracy)
I need to get the most accurate location within 40 seconds.
I know I need to check which providers are enabled, try each of them for the last know location and if it's old or the accuracy is bad then I need to get a network location and check its accuracy if it's bad then I need to fire up GPS and wait max 40 seconds before using the network location.
I am sure this has been done many many times before and I'm wondering if there is a good implementation that I can copy rather than reinventing the wheel.
You can check out my answer to this question: Location servise GPS Force closed
I have implemented the GPSTracker to give callbacks for location changes and for GPS first fix.
Just when GPSTracker has been created it returns the lastKnownLocation until a first fix has been made.
My application keeps track of a user's location, and sets up proximity alerts for nearby stores returned by an API for an automatic-chickin type functionality. I'm hitting my head against the wall trying to figure out how to improve the accuracy when the proximity alert is triggered by network location. I need some way to confirm that the user is at the location by either checking again within a few minutes, or by confirming their current position via GPS.
Part of the issue is that the Context handling the proximity alert is an intent service, so anything that works asynchronously causes issues when the alerts fire in rapid succession. Clearly there's a way to do this properly (e.g. Google+ checkin notifications), but I'm at a loss as to where to look next.
My experience is that network location is often less accurate than GPS location, although neither is 100% reliable. Sometimes GPS will be perfect, but at other times it's wrong my maybe 50 metres or more. To handle the this, I think the best way is to combine the two location sources using a simple Kalman filter, so that neither network or GPS trigger promimity alerts directly, instead it's the result of the Kalman filtering that is used. See my answer to Smooth GPS data for full details of a Kalman filter that might work.
I would like to implement GPS Tracking service. After a search on the web I'm still a bit confused on the best way to practice this feature.
I want to start following the user when he gets a mile away from his home.
I thought that the app will be installed at user's home and using:
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
I'll get the user's coordinates and compare it with changing coordinates as he travels.
When the user gets away a mile from his home I'll send SMS messages with his maps location every predefined time interval.
I was wondering if there is someone who done something similar before and can recommend a best practice for this task.
Also, how accurate the GPS can be, and what might be the best practice to get distance?
Thanks in advance.
From my experience it is not a good idea to use GPS all the time to track when a user departs from his home location because it burns the battery in no time. I ended up learning the home location by looking at the cell tower IDs over night (assuming the user is at home then). If you reach a certain level of confidence that you know the user's home location you can ask him something like "Are you at home right now?" to be completely sure (although this is somehow creepy for many users).
If you follow this strategy you can start the GPS if the user connects to a new cell tower and save a lot of battery.
Regarding accuracy. You can get the accuracy provided with each Android.Location object. If you are outside, this is usually 5 or 10 meters. But be aware that there is only an 68% chance this value is correct, according to the documentation:
We define accuracy as the radius of 68% confidence. In other words, if you draw a circle centered at this location's latitude and longitude, and with a radius equal to the accuracy, then there is a 68% probability that the true location is inside the circle.
Be carefull, the getLastKnownLocation method will not necessary return the user home position.
You shoud rather get the current position. Most of the time, getLastKnownLocation is used to get a location quickly (avoiding heavy background work).
GPS accuracy depends on many factors:
Weather, quality of the chip, field, ...
But, most of the time, it's more accurate that the network provider.
Here a very good link : http://developer.android.com/guide/topics/location/strategies.html
You will learn a lot with that.