In my application i want to receive location updates of different distances from the set point.
In the main activity i have several objects, and each object needs to get location event on some distance from its set point.
I hope i'm clear.
I tried the function requestLocationUpdates with its listener, but in case of several sequential requests, it fires the event only from the closest distance request.
mLocationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 0, 1000, locationListener);
Is there any way to do what i want ?
I do not fully understand what you are asking but it sounds like the new Awareness API might help. https://developers.google.com/awareness/
It allows you to combine location with other pieces of information and only get call backs when they all occur.
My understanding is that you need to receive updates when the device is at different specified distances from a certain point (lat-lng). If so, you may create LocationFences with radius set to your distances and register using Awareness Fence API. When you receive the fence callbacks, you can call the getLocation() snapshot to get the actual location and use that to update your app.
I hope I've interpreted your question correctly.
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.
greetings
I have a ICE Cream sandwitch phone with google play service.
Installed the Geofencedetection sample app from the following
http://developer.android.com/training/location/geofencing.html
I also installed a Mock Location application
Using this mock location i have set my location as new delhi (lat 28.66 long 77.21).
Now i registered the following geofences using the sample app
Geofence1
lat 11.94898
long 79.48475
radius 1000 meters
Geofence2
lat 77.00000
long 77.00000
radius 1000 meters
Now i again opened the mock location and set the
location as (within geofence 1) my home.
lat 11.94898
long 79.48475
I have checked the mock location with the Maps application.
It displays correctly. I enabled the Allow Mock Locations
in Developer options
But the sample Geofence application is not triggering any
notification. I checked the code. As per the code it should send
notification when the user enters the geofence.
I could not understand why it is not sending notification.
Will this work only on real network?
Please let me know if i am doing anything wrong?
Best Regards
jothi
I had a similar experience using the sample MockLocation app from
http://developer.android.com/training/location/location-testing.html
For example if my geofence is set at 5,100 and I use the mocklocation app to inject a single mock location at 5,100, the geofence will not trigger.
However, if you repeatedly inject multiple mock locations at 5,100 the geofence will trigger. In my case, injecting mock locations at 5,100 three times consecutively caused my geofence to trigger. To be clear, when I say inject I mean doing:
mLocationClient.setMockLocation(yourMockLocation);
Everything below is pure speculation on my part so take it with a grain of salt:
My speculation is there is some filtering algorithm in the LocationClient backend whose purpose is to filter out spurious sensor values and it might be detecting that huge change in lat/long as a possible spurious value. Another possibility is the geofence simply doesnt trigger until it receives multiple readings that indicate you are within its vicinity.
Please check notification of app when app in foreground because i am also not getting any update for geofence in background. But in foreground, It is working fine.
I have stuck with this problem for sometime. Then eventually it turns out the google mock location tutorial (http://developer.android.com/training/location/location-testing.html) failed to mention you will need to set below two calls with the mock location you created:
/*
setElapsedRealtimeNanos() was added in API 17
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
newLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
newLocation.setTime(System.currentTimeMillis());
Without these two calls my mock location won't trigger my geofence. After calling these my geofence is triggered without issues.
I also had a similar experience with MockLocation app, just use a large number of seconds on "send interval" field, like 7 seconds, and the geofence will trigger.
After spending a ton of time on this I finally figured out that the secret was to use the provider name "network" when creating the mock location instance.
Location location = new Location("network");
I want to know the accuracy for the every fired proximity alert. Is there any way to get that information? can I use locationManager.getLastKnownLocation()? Is there any way to tell the system not to fire alerts if the accuracy is bad?
I want to know the accuracy for the every fired proximity alert. Is there any way to get that information?
Every update called on your LocationListener is passed a Location object for the new event. This object has methods like getAccuracy() that you can use to obtain that information.
Is there any way to tell the system not to fire alerts if the accuracy is bad?
LocationManager.requestLocationUpdates(), only allows you to control the frequency of updates based on time between or distance between each update. It does not allow you to control getting updates from the manager based on accuracy; you will need to use the information from the update to decide whether or not to keep each report.
How can I get a single GPS fix of my location just by calling one function? Just for this example how can I get the Lat and Lon into a toast.
What have you tried?
Here are two of the official pages for location: http://developer.android.com/reference/android/location/Location.html
http://developer.android.com/reference/android/location/LocationManager.html
But to get the most recent location and show it in a Toast:
LocationManager locMan = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Location loc = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
String lat = String.valueOf(loc.getLatitude());
String longitude = String.valueOf(loc.getLongitude());
Toast.makeText(context, lat+","+longitude, Toast.LENGTH_LONG).show();
If you want to request a new location, it is more code, and I will not cover that here. You can do some google searching or searching on here to find how to use it. The method you need is requestLocationUpdates or requestSingleUpdate. I'm guessing you would prefer requestSingleUpdate
I do not think that you can just make one call and get a location fix. GPS / Android just doesn't work that way. The phone may have a last known location, but that last known location may have been taken/recorded hours ago and miles away. The location returned by the getLastKnownLocation() method has a time stamp and an accuracy that can be used to see if the location is "good enough".
Locations are typically determined by setting up a listener, listening for updates and stopping the listener when you have a good enough fix. See Obtaining User Location for a good worked example, especially the details in the example isBetterLocation() method.
I find it best to create an Asynchronous task that actively registers and deregisters GPS/network/passive listeners depending on whether the application has a good enough location, or not, and have that class export a getMyPosition() method that returns a Location object if a good enough position has been established, or null if not. Then the main code can make a simple one line function call to get the current position. But only because there is an asynch task behind the scenes doing the hard work.
I try to make my asynch task actively deregister the GPS listener and turn off the GPS circuits to save battery live when I have a good enough fix. How long I turn off the listeners depends on the needs of the application. Leaving the passive listener left on (registered) allows my task/application to listen into the GPS position reports caused by any other application on the device "for free".
Getting a good enough position is not a one function call deal, unless you make it so with lots of behind the scenes work.
i'm working on app, which must get latitude and longitude. in my case requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener) is not in option. why? because i must get location just when user do something that location is needed (let's say he hits button). and i need location exactly on the time, when button is hit. in requestLocationUpdates, we can set minTime-if i set this let's say on 30000 the location at the "button hit time" won't be as good as i want. of the same reason minDistance is also not as good as i want. if i understant function requestLocationUpdates correct-when minTime and minDistance are set to 0, location is updating all the time. please correct me if i'm wrong. app is for company that i'm working at and that app will be used through the day and night. so if app will check for location updates all the time, battery would be often empty. thst's why i need location just at the time, that button is hit. i found requestSingleUpdate function. but i can't use it in eclipse =( like it doesn't exists.
is there some other way to do this or am i missing something?
The requestSingleLocation method new for API level 9. If you are targeting an earlier API level, this method will not be available to you.
One of the problems with obtaining location information is that it can take time to get a fix. This is more of a problem with the GPS location provider than the network provider. If you are only using the network provider, then there may not much of a delay with getting the location information when the user clicks the button (I say this knowing nothing about what your app does with the data, or what type of user experience you are trying to provide).
Something else you can try is the PASSIVE_PROVIDER. It allows you to get location updates that were requested from other apps. This will mean that you have to request the ACCESS_FINE_LOCATION permission however. You may also need to leave something running to receive the location updates (likely a service or a BroadCastReceiver). The BroadcastReceiver approach should not use that much additional battery life since it only runs when the Intent is received along with the PASSIVE_PROVIDER only getting locations when some other app requested them anyways.
The other sticky point with the PASSIVE_PROVIDER is that you should eventually call removeUpdates. Where and when to call this really depends on how your app is structured and how you handle the user exiting the app.
You can use getLastKnownLocation method, but it can be out-of-date. requestLocationUpdates is asynchronous because gps needs to "warm-up" to find new location.
requestSingleUpdate method is available since api level 9, but you can implements it's using requestLocationUpdates and disabling updates after first callback to LocationListener.