Android: Best way to get instant location once per use - android

I always had some difficulties to find a good way for the instant location of the device.
What I want to do is once per use of the app (e.g. when the onCreate of an activity is called) i want to know the coordinates of the device in that exact moment and never ask for them again.
What I think could be the best way is to have something like a static Class with a function similar to :
coordinates getCoordinates();
Some advice/snippet to give?

Use LocationManager.getLastKnownLocation or LocationManager.requestSingleUpdate.
The first will return immediately, but may return null if no location is already available.
The second will return your data on a callback, but will wake up whatever provider is needed and will get a good location (if possible).

I have found what I really was searching in THIS answer.
I have only added two controls; i check if:
gps_loc.getTime() (or net_loc.getTime()) is bigger than System.currentTimeMillis() - 300000 (5 minutes ago). In the method run() of the inner class GetLastLocation;
location.getAccuracy() < 100. In the method onLocationChanged() of both LocationListeners (network and GPS).
Hope it helps!

Related

Android - Get a GPS Update based on specific amount of Time AND a specific distance travelled

I want to get location updates every 60 seconds OR every 1500 meters traveled.
Obviously, the LocationManager allows you to set a minimum for time and meters, but the GPSUpdate will not trigger until both the time and distance minimums are met.
But what i want is to have the GPS Update every 60 seconds (no matter how far the user has traveled) and every 1500 meters (no matter how long it took).
I have tried using multiple locationClients with the locationRequests set to each criteria, but they both cannot connect at the same time.
Is there any simple way to achieve this?
Apologies for never posting back, i had forgotten all about this question.
Whatever my solution was in the past would not have been correct as i recently added a more efficient way to do this.
First.. if you are using FusedLocationAPI and GoogleApiClient, then see my answer posted here.
If you are using the LocationManager class and not the GoogleApiClient, then the solution is similar.
You need to create two requestLocationUpdates, one for Time only, and one for Distance only, with the unused field set to 0, for example:
locationManager.requestLocationUpdates(bestProvider, 0, UPDATE_MIN_DISTNACE, myBackupLocationDistanceIntervalListener);
locationManager.requestLocationUpdates(bestProvider, UPDATE_TIME_INTERVAL, 0, myBackupLocationTimeIntervalListener);
This can also be done with Criteria if need be:
locationManager.requestLocationUpdates(0, UPDATE_MIN_DISTNACE, gpsCriteria, myBackupLocationDistanceIntervalListener, Looper.getMainLooper());
locationManager.requestLocationUpdates(UPDATE_TIME_INTERVAL, 0, gpsCriteria, myBackupLocationTimeIntervalListener, Looper.getMainLooper());
Then just define your listeners. You can use either the same or separate listeners to handle the results from the requests.
Hope this helps.

How to get programmatically the data usage limit set by user on Android OS configuration?

User can define at Data Usage screen a limite and/or a warning limit for mobile data usage. So how can I get this information by code?
Screen of Data Usage configuration of native OS.
I wanna the limit value and warning value.
I've already tried this but not work and always return NULL to both:
final Long recommendedBytes = DownloadManager.getRecommendedMaxBytesOverMobile( this.context );
final Long maximumBytes = DownloadManager.getMaxBytesOverMobile( this.context );
// recommendedBytes and maximumBytes are NULL
And TrafficStats class just have a data transferred not the limits.
After days searching and research about this problem I couldn't find a answer for that. Bellow I will lift every attempt that I did.
1. Download Manager
With this class you can start download over any network or device
state and it will handle all states e.g. network loss, device reboot,
etc...
There are two methods called getMaxBytesOverMobile and
getRecommendedMaxBytesOverMobile, they was a pretty candidate
to solve this problem at first time. But after code tests and
Download Manager implementantion research I'd found that there is
no way to get thoose values by DownloadManager.
Reason
Thoose methods call Settings.Secure.getLong with they
respective labels
Settings.Secure.DOWNLOAD_MAX_BYTES_OVER_MOBILE and
Settings.Secure.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE in
the turn makes a call to a lazy String map inside inside a
inner class called NameValueCache.
Ok so far but none of inner classes or Settings implementation it
self use DOWNLOAD_MAX_BYTES_OVER_MOBILE or
DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE inside.
I considered the lazy map was populate by a third entity, what
actually happens, so I found the NameValueTable Settings
inner class that handle the new values to lazy map. The
putString is a protected method call by Settings.Secure
and Settings.System inner classes (calls of Secure and
System).
So I could conclude that if the OS implementantion do not put thoose String values I can't get them.
2. TrafficStats
Just a quick look on official reference I could notice that it will
not help me because this class just provide the amount of bytes and
packages that was trafficked since last device boot.
http://developer.android.com/reference/android/net/TrafficStats.html
3. NetworkPolicyManager and NetworkPolicy
As #bina posted here the both classes are hidden and could not
be use by normal apps e.g. that will be published in Google Play.
https://stackoverflow.com/a/24445424/575643
4. ConnectivityManager
In short, you just can get the NetworkInfo that not provide
much information about user preferences (really none!). Just provide
informations about network and e.g. mobile network provider.
http://developer.android.com/reference/android/net/ConnectivityManager.html
After all I assume that no way to get this information nowadays. Please if you read it and found a way post here!
Thanks for all.
PS.: Sorry by english mistakes.
Do you want to get limit value(5GB) and warnning value(2GB) in this example?
If so, you can get limitBytes and warningBytes by the following code, if you can use android.permission.MANAGE_NETWORK_POLICY and android.permission.READ_PHONE_STATE.
However, android.permission.MANAGE_NETWORK_POLICY protectionLevel is signature.
NetworkPolicyManager manager = (NetworkPolicyManager) getSystemService("netpolicy");
NetworkPolicy[] networkPolicies = manager.getNetworkPolicies();
Log.d("NetworkPolicy", "limitBytes is " + networkPolicies[0].limitBytes);
Log.d("NetworkPolicy", "warningBytes is " + networkPolicies[0].warningBytes);
(NetworkPolicyManager and NetworkPolicy classes are hidden)

What does getSpeed() actually do inside of Android?

I am writing an app which uses the onLocationChanged(Location location) callback along with location.getSpeed() to get the speed at which the user is traveling. I am curious as to what actually occurs when getSpeed() is called. I note that location is just a parameter fed into the callback by Android, which leads me to wonder:
is getSpeed() simply pulling an already-calculated field from this object, or does calling getSpeed() calculate the value in some other way?
I'm also curious many times what is in the source code or how is it called. I tried to find the code of android.Location class and it seems I'm succesfull.
Try to check out this page: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/location/java/android/location/Location.java
The method 'getSpeed' is at the row number 627, but it tells only 'return mSpeed;', so you have to look to the other parts of the class
Android's getSpeed() will just return the value that was set in setSpeed().
The best way to get speed is to use simple physics:
Speed = Distance/Time
The thing about GPS' is that there is a lot of variability and thus accuracy isn't always the best in terms of speed. You should use a filter to help smooth the data (The Kalman Filter is pretty popular for navigation data).
Good luck!

LocationManager best implementation?

Is it advisable to implement both LocationManager.NETWORK_PROVIDER and LocationManager.GPS_PROVIDER with the differenct listener and then unregister the listeners locationManager.removeUpdates(locationListener) ?
Because GPS_PROVIDER takes lot of time to return the values and sometimes doesn't even gives a call back?
Also, we can have a locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); in handler with a postDelayed to avoid a deadlock in case there aren't any callbacks?
Any help by anyone?
Thanks in advance!!!
BR,
J
Hm afaik locationManager.getLastKnownLocation returns instantly, so you should not see any deadlocks?
If you really need to manage your own LocationListeners, it is advisable to first register a Network-One and a two GPS-ones. Use the network-Listener to receive a first location (rough). Configure one GPS-Location-listener to receive all GPS-Updates. Once the location is accurate neough, switch to a managed GPS-Location-Listener, that only receives updates every x seconds and x meters diff. See http://developer.android.com/guide/topics/location/obtaining-user-location.html for more examples.
If you want to display the location on a map, try MyLocationOverlay. It does all that for you.
Ideally this question wont be valid anymore, since Google finally released newer version of location listeners which would take care of this more effectively.
Link for the same below:
http://developer.android.com/google/play-services/location.html

Android gps how to skip distance?

I am working on a GPS-enabled application and I need to record a point each N meters. However, I can't see how I can use onLocationChanged() method in the LocationListener or any other method/class. The onLocationChanged() method gives a point each second, and I need to store each N-meter point.
I believe that this has a simple solution, but since I am beginner in Android, cant find it.
Any help will be much appreciated.
requestLocationUpdates has a minDistance parameter, that
if I recall correctly does what you want. I haven't been able to test this on a real phone though, so I don't know how accurate it is.
In onLocationChanged, compare the location you get with the last one you stored. If it's less than n meters, discard it. If not, store it. Rinse. Repeat.
EDIT: Wait, even easier - doesn't requestLocationUpdates have a minDistance parameter? See here: http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates
it is working perfectly
myManager = ((LocationManager) ApplicationController.getAppContext().getSystemService( Context.LOCATION_SERVICE ));
myManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1 * 1000, 0.00001f, this);
mintime =1000ms always it is calling ....

Categories

Resources