How to reduce battery drain while using large number(50) of geofences - android

My requirement:
Area around the Path(Route) is having some important places(quantity is approx. 50). When user is moving on the path, and reach to the nearest place(e.g. A), I need to perform some task particular to that place(e.g. A).
Currently, I am creating geofences for all the required places at the same time but having doubt about the battery consumption.
Is there any way to minimize the battery consumption? If yes, then please help. Any help or guidance will be well appreciated.
Note: User can enter to the route from start/end/middle of the route.

Here is one option:
Run each point through an algorithm to determine the distance from the point to the user. For example lets say the user is at X(0),Y(0) run the root of (Xn - X(0))2 + (Yn - Y(0))2
Assign the distance as a property of the geofence.
Sort an array of the geofences for the new property.
Add the 10 closest (or whatever number seems reasonable based on the distance of the path and proximity of the geofences with one another) regions to a new array.
Register those 10 (or so) regions.
Record the last location at which this process was done and compare it with the users current location. If the user travels a certain distance than begin the process over again.
Especially with the simple math operators this is much easier on the OS than searching for 50 regions simultaneously.

Related

How often should I track device position in Ionic 2 (e.g. Uber, Taxi Apps, ...)

I am studying the Cordova geolocation plugin for Ionic 2 and want to send the device location to my server when the app is opened.
To keep track of the route of the device I want to send the position all the time to the server. I was wondering how often I should do this. Every time the location changes seems a little too often!?
How do other tracking apps do this?
Granularity of position updates are inversely proportional to the battery power consumed and the network bandwidth used for transmitting the positional information.
I use the following guidelines:
Transmit position whenever the position has exceeded a defined distance 'D'
Transmit position whenever a defined period of time 'T' has elapsed since the last successful transmission
Transmit position when the app starts
Disable transmission when the activity is paused and enable it when the activity is resumed
Always save the last successful transmission (position and time stamp) for future reference
I typically store the defined parameters 'D' and 'T' in a configuration file, making it handy to test how the application performs for different values.
Using coarse GPS for reference, position accuracy is rarely better than 15 meters (without applying GPS corrections). With that in mind, you can set your 'D' value to something between 15-30 meters. If you are tracking vehicles, that distance can be exceeded pretty quickly, in which case a larger value may be preferable to avoid sending too much data.
You can also increase 'D' as a function of your positional velocity (speed). this would increase 'D' the faster the vehicle is moving, thus maintaining a consistent bandwidth usage.
The value of 'T' really depends on your application needs. If a vehicle is sitting idle, then I typically transmit updates once every 5 minutes.
I have used distances ('D') between 30-100 meters. If you are monitoring vehicle positions in an urban environment, you need to be able to pin point where that vehicle is within a crowded street plan. This becomes quite clear if you've ever used a GPS device to navigate in an older city, where the device often gets confused between streets that are in close proximity (i.e., New York, Boston, Montreal, etc.) In this case, a smaller value (> 15m) is preferable.
For added robustness, you might want to add some heuristics into your application. For example, popular after-market GPS devices for automobiles have to implement more intelligence into their applications, in order to snap the vehicle position to a location on a street or road. Otherwise, the vehicle would never show up on the street itself, but rather somewhere in the ditch, or right in the middle of a building on the map.
One example of such heuristics would be to assume that unless the vehicle has reached an intersection, it is still on the same street that was reported previously.
Ultimately, you need to try out different configurations in order to find what best suits your needs.

Proximity alert for locations saved at server

I did some search but could not find a suitable answer.
My App should compare with multiple locations for proximity. This means I will not be able to save all the locations into my app to confirm the proximity using locationManager. I want the proximity confirmation to be done in the server
What would be the best way to implement this?
Would it be sensible if the app asks for proximity confirmation every time the devices moves around?
I would try a different approach, since location updates from GPS are made once per second,
and I don't think it's a good idea to ask the server each second for proximity if you have a large amount of devices.
Think of this idea -
Get the device's initial location and send it to the server.
Decide on a sensible radius that the device will stay within it for the next 5-10 minutes.
Also make sure that you don't have "too many" points in that radius, or you can narrow the radius in that case.
It's up to you to decide the radius and the number of points, depending on your usage,
number of points etc.
Send form the server all the locations within that radius to the device.
Let the device calculate the proximity by itself.
When the device moves out of the initial radius - update the server and get the new
relevant locations.
This can be done easily - call the radius r. Save the initial location of the device, and calculate the distance
between the current and initail location. When it is "close enough" to r - update the server.
In your case, simply, you can send the received locations to your server and then make required calculations on server. But don't forget that you will be dealing with those questions
How many devices send location to server ?
How frequently each device send location to server ?
Also the responsibility of detecting a device has entered an area on the server
I think you can reduce the complexity of the all things by using geofencing api, link
No need to send each location to server.
Each device individually detects itself has entered or exited an
area.
EDIT
Otherwise you will be doing entered/exited calculations on server for unlimited count of device, whenever each device's location has changed.
Before we were doing similar thing in my previous company, calculating enter/exit time and enter durations. but via real gps devices on buses
We have almost 100 points(geofence) in city. So you can think that those points are on a few routes
Each gps device on bus is sending location to server periodically.
When the bus has finished it's route, server reviews device's all received locations on the route.
Compares each geofence with each location of bus.
This is the real scenario. You can call it "server based geofencing".
You could do a simple k-d tree implementation on the server side to store the coordinates.
Send the coordinates of the device over, which can be determined at whatever interval you need. If it's every 5 seconds, or 10 seconds it doesn't really matter. This will mainly be decided by the minimum distance between each of the coordinates/radius. If they're closer, you may need to update it more frequently.
Using the k-d tree finding the nearest neighbor would be O(log(n)). However, you make a slight modification where you can start adding the nodes to a list as long as they are within the certain radius of your device coordinates. In fact if you store it locally as a k-d tree as well then you can pick the furthest nodes in O(log(n))
Now on the second update when the device location is sent again, you can quickly update it since you have the existing locations. Say you move in the x direction by 5. You can drop the points that are now outside of the radius at x - 5. The new proximity, you do the same nearest neighbor search, adding in nodes as they're within the radius, but this time starting with the cached nodes closest to the direction you are moving in.
Combining that with an interval tree for radiuses. So say 0 to 1, 1 to 2, 2 to 3, as your intervals. You can pick out everything within a certain radius in O(log(n)) time as well. Those should be pointers to nodes in the k-d tree. That would simplify the radius calculations and finding the location if you're willing to sacrifice some memory for efficiency.
For a "fast" way to implement it on the server side you can use the mondodb $near geospatial query.
https://docs.mongodb.org/manual/reference/operator/query/near/
While on the mobile side you can use the minDistance property for the location updates. You can set it to a reasonable distance 20m/50m depending on the average distance between your locations.
http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)
There is a free service for this purpose -> Radar
You can register unlimited circle or polygon geofence, and register your user in app for tracking that user. When user entered in one geofence Radar send a notification to your server and send below data to you:
User ID, Geofence ID that user entered or exit, Confidence (low, medium, high) used for geofence that has overlap.
You can use this SDK in only 10 minutes.

Android: Right approach for sensing the distance between current location and some point of interest?

I have a question regarding my programming approach for android - whether it's efficient or not. Just to give you an idea what I try to accomplish:
There are multiple points of interests on a map. If the user gets nearer to a PIT, a notification about the distance shall appear. There are let's say 3 notifications: At a distance of 1 mile, 0.5 miles and 0.1 mile. When the user is more or less exactly at the PIT, no more notifications are shown. The user is supposed to drive a car or another vehicle.
I'm currently using Geofences to detect whether the user has entered a radius of 1 mile. If so, I check the distance of his current location to the PIT. If it's about 0.5 or 0.1 miles away, a notification is fired. Therefore, I check the current location frequently (right now every 10 seconds). If the user is like at the PIT or rather very close, the Geofence is exited and done.
The code is working fine and this approach is the first thing that came to my mind while reading the Android Developer's tutorials etc. But is there another approach that is MORE EFFICIENT?
Although this is (currently) meeting my needs, I have two major concerns:
It seems to drain the battery quite a lot. Since the user is most likely to be in a car where he can charge his phone during usage, this might be less of a problem.
I read the number of PITs from a file on the SD card. In my example I have just a few PITs. But the user is able to modify the source data so that he can add as many as he wants to. Google says that only 100 active Geofences are supported per user. But what if my user has more than 100 PITs? Since I'm using a Geofence to sense whether I have to fire the first notification or not - this is a severe problem. So is there an alternative?
I have a few suggestions :
1) To lower the amount of gps fixes, you could calculate a sleep time. The idea is to do frequent gps fixes when near a 'border' and few when far away. This could be further enhanced by taking the speed parameter returned by the GPS into account.
If for instance the user is 20 miles from the nearest border while driving 20mph, you can easily wait 30 minutes before turning on the gps again, just to give a simple example.
2) I have run in to the same problem. My solution was simply to select only the POI's within X miles. This way ensuring never to risk hitting the limit of 100. When the user has moved (X-1) miles from his initial position, the geofences are rebuild using the new location.
If you think there is a high risk of having such a high density of points that the above strategy still might fall, I would consider making your own proximity checking entirely based on gps instead of geofences.

Performing an action based on location

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.

Do something when phone reaches a set of location?

I have a list of coordinates in the database identified as POI. For a city could be >100 records.
I would like to get notified when the phone gets in 150 meters range of one of the location. The location coordinates too has an error/radius, usually 10 to 100meters. Since I don't find it good to add each location(could be hundreds) for a trigger, how can I optimize the wake-up code?
Also do I have options to remove a previously setup notification from the queue?
You could store your POIs in some sort of intelligent Hash-Table using the coordinates to compute a unique hash. Each time a location update arrives you make a lookup in your hash-table to see if there are POIs near the current location. This lookup should only take O(1), since it is a hash-lookup.
The desired range should be taken into account when computing the hashes and storing the POIs.
Just an idea!
Kind regards,
mefiX
There's an app named Locale, that can toggle various events based on your GPS location OR available Wifi network OR cell-station id, etc
It also has a plugins interface. It could be useful for you to examine that app and, maybe, write a plugin for it.
This problem reminds me of graphics in video games. There's no need to load the points that are well outside your range of movement. I'd break down the map into a grid, set triggers for the 8 adjecent grid blocks and then for each of the POI within the current grid block. When a new grid block is reached the triggers are updated. It'd probably be smart to overlap the grid blocks considering the range of error.

Categories

Resources