Increasing the accuracy of proximity alerts in Android - java

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.

Related

Getting an accurate path history via background service in android

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.

Know when phone enters building on android device

I was wondering if there is a way for me to detect if the users device is being "obstructed" by a building or roof of some sort. Im developing a very precise location based app and its KEY that my users get alerted if something is wrong with there GPS or something is getting in the way. Physical object.
EDIT: The app ive created strictly takes snapshots too its not something thats constantly going. Just a quick snapshot.
Not directly. You can try calling LocationManager.getGpsStatus and iterating over the list of satelites every so often and looking for a jump in signal to noise ratio since the last reading. Getting a working algorithm is going to take a good amount of work and testing on a variety of devices with different GPS chips.

GPS Location Tracking

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.

apps, remote sripts and security/obfuscation

I will construct a fictional app in order to construct my question.
I write a kind of treasure hunt app where the user gets a prize if they visit several locations around town. In effect the app would get their current lat/lon and check its proximity to the list of "treasure locations", if they are within 10 meters of any treasure location they get a notification.
The app will then do a http post to a remote script which basically inserts into a database. The post parameters will be uuid of device and the location they visited.
An attacker could easily watch wireshark and get the name of the script along with the parameters. They could go further, decompile the apk and get other things such as any hashing/obfuscation. They could then just use curl to post willynilly as they pleased and the game would be ruined for non-cheaters. This is a problem have never had to really address since in all the apps I have written there is always data which isnt sensitive and I dont mind it being exposed to the public.
What do I do?
The best think you could do is to send the data in a secure manner. Using HTTPS would be a much better choice, regardless of method. This effectively prevents eavesdroppers, it is the fundamental technology behind any secure communication on the internet.
Aside from the protocol to communicate with the server, there are still insecurities. Essentially, there are three methods that could work to overcome these.
The location of the player could be sent to the server at some periodic interval. The server responds back if they are close enough to one of the areas. Perhaps the server could include enough smarts to know that it takes time to get from point A to point B.
A single location could be sent at a time to the app. The track of the user could also be uploaded, to verify that the location is correct.
The locations could be sent through a one way function to the program. The real answer could be then sent to the server. The problem with this is that the exact location would need to be discovered in order for the same hash to result back. However, as GPS coordinates tend to only be accurate to a few meters, and don't tend to give insignificant digits, then multiple values could be tested near the current location. The one-way function would have to require some time to calculate in an effective manner, as otherwise it would be trivial for a bad guy to simply test every square meter in the city to figure out what would work.
The best method from a security standpoint would be the first, as at no time does the application know where it is supposed to go, until it reaches that location. Of course, this pings the server a large number of times needlessly.

how to calibrate the orientation sensor in android?

I'm writing an app in Google Android 2.1 that needs to know which direction (n/w/s/e) the device (HTC Hero) is facing. The sensor and its listener are working great, but the values I get from the sensor are totally crappy. e.g. it tells me I'd be facing north when the device is facing SW or so...
This seems to be a known problem with android devices. The "solutions" I found on the web look like this:
shake the device around
move the device like an eight
tap on the devices back
This is thought to trigger the sensors recalibration. And: the thing with the "moving around" works for me... but that's not very professional I guess...
so - how do I trigger the recalibration of the orientation sensor from the SDK? I need the sensor to be properly calibrated without any fancy stuff that would make users of this app look like complete idiots while they are "manually" recalibrating their phones...
Is there any way to do this "right"?
EDIT:
Or: is there any way to determine PROGRAMMATICALLY, if the device is correctly calibrated or not? As a fallback-option so to speak... then I could warn the user that the device needs "manual" recalibration.
I don't believe there is a way to know programatically if you compass sensor is calibrated correctly unless you use a secondary data source like GPS. If you can use GPS then when the user is moving you can compare the GPS movement with the compass heading and correct. Remember that local magnetic fields can screw up the compass readings and the devices has no idea if you are out in the middle of a forest or next to a transformer.
With these micro devices there is always a bit of skew you'll have to deal with. If you check the values for the accelerometer as well you'll see that at rest they aren't always returning 9.8 m/s^2 (or at least consistently between devices).
In your help you may just need to tell the user to rotate/twist their phone in a figure eight to reset the compass.
I assume you are referring to the Magnetometer inside the Hero.
Callibrating it is a tough one and will/should always require user interaction for a realiable callibration. There are seperate strategies to deal with that. You could ask users to hold there device in north direction and then recallibrate. If the users don't know where north is, you can ask them to direct zhe device towards the sun and based on location and time you can calculate where that is.
Leaving callibration aside, I would guess that your problem is that the readings you get from the sensor are inaccurate. Of course callibration is a prerequisite for accurate readings, but there are also other factors in play.
It is common practice to complement sensor data from one sensor with the data a different sensor to increase accuracy. You could use the GPS to determine a heading when the user is moving. If he's moving slowly however, this is inaccurate as well. You could integrate the data reported by the Accelerometer to guess about orientation changes (not the absolute orientation). But honestly a Gyrometer would be more ideal in this case.
Systems that work like this are sometimes called Inertial Navigation Systems (INS) because they can, given a fixed point in space, determine their subsequent relative position and orientation accurately without further external data. Using a Kalman filter is common practice to recallibrate the system from time to time when an absolute position (e.g. retrieved via GPS) is available.
Although it is unrealistic to implement a full-fledged INS, you can certainly draw a few ideas from how they work to make your orientation readings more accurate.

Categories