I'm using flex 4.6 mobile application my issue when i get the current location using gps sensors it take alot of time Within the limits of 35 sec to take 2 updates my code is
protected function GetGPSposition():void
{
//Initialize the location sensor.
geo = new Geolocation();
if(! geo.muted){ //gps is enabled
geo = new Geolocation();
geo.setRequestedUpdateInterval(10);
geo.addEventListener(GeolocationEvent.UPDATE, handleLocationRequest);
geo.addEventListener(StatusEvent.STATUS,handleErrorGPS);
}
else if(geo.muted){ //gps is disabled
(new GPS2()).open(this, false) ;
internetGpsEnable = false ;
}
}
protected function handleLocationRequest(event:GeolocationEvent):void
{
counter++ ;
if (counter > 1)
{
long = event.longitude;
lat = event.latitude;
internetGpsEnable =true ;
lblGPS.text = null;
}
}
Note : GetGPSposition() worked in creationComplete
Can any one to advice me if any method to get the longitude and latitude fast as possible .
Thanks in advance for help.
The GPS of an android device runs in an idle state until requested to save battery, once requested it takes time to communicate and calculate, you can't make this process faster.
If you have both fine and coarse position permissions the Geolocation API should report the Radio/GPRS location while the GPS resolves, but this isn't exact.
I believe your method is as fast as it is possible to go, short of calling into Geolocation when the app starts, to ensure its always polling.
Related
I am developing an App into which i am taking user current location using FusedLocationProviderClient. something like below code.
I am not able to understand why it takes current location as different location sometimes its 2+KM far away from current location and device is just stable at one place
private void getLastLocation() {
try {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLocation = task.getResult();
onNewLocation(mLocation);
} else {
Log.e(TAG, "Failed to get location.");
mLocation = null;
}
}
});
} catch (SecurityException unlikely) {
//Log.e(TAG, "Lost location permission." + unlikely);
}
Above code is in a foreground service... Now issue is when user device is stable yet after 5-6 hrs running the app it returns different different current location even though device is at same place(no movement )
Actual result : it should not give me any km traveled by user.
my KM traveled by user calculation is something like below code
double distanceInMeters = currentLocation.distanceTo(priviusLocation);
if (distanceInMeters > getSharedPref.getDefaultDistance() && (mLocation.getAccuracy() < Config.ACCURACY ) //Config.ACCURACY==>70{
// if (distanceInMeters > getSharedPref.getDefaultDistance()) {//getSharedPref.getDefaultDistance()==>10
if (mLocation.getLatitude() > 0) {
getSharedPref.setPreviousLocation(String.valueOf(mLocation.getLatitude()), String.valueOf(mLocation.getLongitude()));
writeDataInLogFile("this set to previous ", String.valueOf(mLocation.getLatitude()) + " getLongitude " + String.valueOf(mLocation.getLongitude()));
}
data.setGPS_Km_Travelled(String.format("%.2f", distanceInMeters / 1000));
data.setGPS_Is_Loc_Changed("1");
}
The way the fused location provider works is that it combines data from a device's GPS as well as network information from Google using the device's cellular network and WiFi information as well as perhaps other information from your device.
What sometimes happens is that when you leave a device in an area where there is little to no GPS connectivity, the user's position is inferred using network information from the device. This is sometimes as accurate as 30m but sometimes the position given by the fused location provider can be as inaccurate as a few kilometers.
Due to this your app may think the device has moved since the current location has changed even though the physical device never moved.
In order to fix this it's necessary for you to implement an algorithm to filter received positions based on certain criteria. For example, if the position has an 'accuracy' value higher than maybe up to 100m then it's not even worth considering as a valid location since the user might actually be up to 3km away from the location the api is returning.
Also, if the user's current location is too far away from the last location then the you should check whether the new location can be trusted as being accurate (a person can't usually move at a speed of more than a few km/h)
Good luck with your endeavours!
I have developed an android application which took the current location using GPS every 10 seconds, and send it to the server using socket. To achieve this I used postDelayed method to keep getting current location and send it to server.
myRunnable = new Runnable() {
#Override
public void run() {
Location mCurrentLocation =getCurrentLocation();
if(mCurrentLocation != null)
sendCurrentLocationToServer(mCurrentLocation);
Handler.postDelayed(this, 10000);
}};
public Location getCurrentLocation(){
Location currentLocation = myLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return currentLocation;
}
but this code makes the device to overheat, and consumes the battery quickly, is there another way to achieve the same result and reduce the overheat?
Thanks
First off, don't use getLastKnownLocation. Not only will it normally return null, looping calling it is an EXTREMELY inefficient way of doing things. Instead, requestLocationUpdates, and it will call you when it has a new location.
Second, don't send the location to the server every 10 seconds. Sending it that frequently causes your phone to keep the radio (either wifi or cellular) on constantly, which is causing your heat issue. Sending data generates heat. Reduce it to once every minute or so, and send up heading and speed data with the location. If you need a more exact location the server can use speed and heading to programmatically calculate a probable location- if needed. Most likely you don't even really need that.
I am building a GPS Android application which gets the nearest places based on the user's current location.
This is what my application does:
Check if GPS or Network is available
If neither is available then don't do anything. Else, we first check for GPS if it's there, if not then we check for Network.
After using one of them, we get the current location and then send it off to the server.
Once we retrieve data from the server and update the UI, we stop listening for further location updates. Once is enough, until they press the refresh button which starts this again.
What I hope to do:
If GPS or network fails to retrieve a location, for example, 2 minutes, then we switch providers. We don't want the user to wait too long.
It would also be nice to be able to use both providers and then get the most accurate from that. I've taken a look at http://developer.android.com/guide/topics/location/strategies.html and I saw the isBetterLocation method. How would I integrate this method in my application? I'm having trouble understand how, where and when it should be called. I assume that the isBetterLocation() requires me to call both Network and GPS at the same time. It would be nice for my application to listen to both for accuracy. How do I do this? What if one of them isn't available?
Here's parts of my code:
if(!GPSEnabled && !networkEnabled)
{
Toast.makeText(this, "Error: This application requires a GPS or network connection",
Toast.LENGTH_SHORT).show();
}
else
{
if(GPSEnabled)
{
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else if(networkEnabled)
{
System.out.println("Getting updates from network provider");
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
}
This is the onLocationChanged method. I get the lat/lng values and then send them off to my server and then do appropriate stuff with it.
public void onLocationChanged(Location location)
{
//Get coordinates
double lat = (location.getLatitude());
double lng = (location.getLongitude());
Log.d("MainActivity", "got location: " + lat + ": " + lng);
//get nearest locations
new GetLocations().execute(SharedVariables.root + SharedVariables.locationsController + SharedVariables.getNearestMethod + lat + "/" + lng);
// Zoom in, animating the camera after the markers have been placed
map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 10));
System.out.println("lat = " + lat + ", lng = " + lng);
//Stop listening for updates. We only want to do this once.
locManager.removeUpdates(this);
}
Either using GPS or the network, you can't drastically reduce the eventual waiting time to get your location.
Both of these location methods have their disadvantages and advantages:
GPS usually takes a longer time to know your location, because finding and calibrating GPS satellites is a tremendous task (finding at least 3 correctly-aligned satellites is required). On top of that, add the eventual obstructing objects/environment blocking the signals. Unless you enable GPS before/when your app starts, wait is mandatory. On the other side, you get a fine-grained location.
If you only need a rough location, using the network is a solution: it returns data in a few seconds. However the precision of the location varies depending on the available/used networks; I don't have any practical examples, but I guess the precision can greatly vary. GPS will ALWAYS have a better-grained location than network.
Understand there is no predefined choice. Anything depends on what your app does with this data.
Use GPS if available, while making the location request to the network, and fall back to network if there is no GPS device. Then take either:
the first-coming result if you just need a location
the preferred result if you want the most precise data
If GPS or network fails to retrieve a location, for example, 2 minutes, then we switch providers. We don't want the user to wait too long.
In both cases, do not make a fallback timer: you'll just lengthen the waiting time in the case where the first provider fails; so do both request at the same time, unless the android API does not permit asynchronous location requests.
My Device gps found satellite but doesn't lock. It keeps constantly trying to acquire the GPS signal, but most times it fails. I tested it on other android version 4.1.1 and the problem persists.
I just tried many combinations of resetting both Google location services and the location access and nothing fixes it. I go into maps and I can't get a gps lock at all. I've noticed, it takes longer to get a GPS signal, and the signal gays lost more often
Disabling the 'Google location services' also doesn't work
In every app that uses GPS only the empty circle shows up. Sometimes (after many seconds) the dot appears and starts blinking. But even after three minutes my phone is searching for a GPS signal.
On official google map app, It say searching for GPS signal and stays like that
I don't have any bug report.It just looking for satellites all the time, in some point there is only circle without the dot inside.
sample code used to get GPS coordinates
#Override
public void onCreate(Bundle savedInstanceState) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria c = new Criteria();
c.setAccuracy(Criteria.ACCURACY_FINE);
c.setBearingRequired(true);
pro = locationManager.getBestProvider(c, true);
locationManager.requestLocationUpdates(pro, 0, 0, this);
Location loc = locationManager.getLastKnownLocation(pro);
gpsManager = new GPSManager();
if (loc != null) {
showLocation(loc);
}
#Override
protected void onPause() {
locationManager.removeUpdates(this);
}
Is there any solution?
My favorite tool for debugging GPS issues is the GPS Test app. It shows you how many satellites your phone is detecting, how strong their signal is, how accurate the fix is, etc. This at least lets you rule out if you're in an area with bad satellite coverage.
I've only got one app on the market, but it is a GPS based app. Here's some of my code that got things working. Mind you, this only uses the GPS, it doesn't do rough location based on network.
public void initLocationManager()
{
myGpsManager = (LocationManager)getSystemService(LOCATION_SERVICE);
long time = 0;
float dist =0;
myGpsListener = new locationListener();
myGpsManager.requestLocationUpdates("gps", time, dist, myGpsListener);
}
#Override
public void onPause()
{
myGpsManager.removeUpdates(myGpsListener);
super.onPause();
}
Background
I am writing an Android app whose main function is tracking the user's location and making an alert when the user gets near some point. Therefore I need to update the user's location at regular intervals, and these intervals should get smaller as the user comes closer to the target. So when the user is within, say, 1 km of the target, I want the location to be updated every 20 seconds and so on, until the user arrives.
Problem
When I test it (provider = LocationManager.NETWORK_PROVIDER), a call to requestLocationUpdates(provider, minTime, minDistance, locationListener) with any minTime < 45000 has the same effect as minTime = 45000, i.e. I get updates with an interval of exactly 45 seconds.
I know the minimum time parameter is only a "hint", but it is not taken as a hint by my app. I get updates with the interval specified until that interval passes below 45 seconds. It seems as though a minimum time of 45 seconds between location updates is hardcoded into Android, but that would be kind of odd. Plus I have never heard of this problem before, and I have not been able to find it addressed here on Stackoverflow.
Because I am not able to get frequent updates, my workaround (for now) is to manually call requestLocationUpdates whenever a new location is needed, and then just use the first available location. To do this at small intervals I use handler.postDelayed(myRunnable, updateInterval) to delay the calls, and myRunnable then takes care of calling requestLocationUpdates. However, this method only works about 50 (apparently random) percent of the time.
Does anybody know of the problem, and is there a way to fix it? Or is my only option to set minTime = 0 and just hope for the best?
Source code
Here is the source code for myRunnable, whose run() method I manually call regularly with handler.postDelayed(myRunnable, updateInterval):
public class MyRunnable implements Runnable {
private LocationManager manager;
private LocationListener listener;
#Override
public void run() {
// This is called everytime a new update is requested
// so that only one request is running at a time.
removeUpdates();
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new LocationListener() {
#Override
public void onLocationChanged(Location loc) {
location = loc;
latitude = loc.getLatitude();
longitude = loc.getLongitude();
accuracy = Math.round(loc.getAccuracy());
handler.sendMessage(Message.obtain(handler, KEY_MESSAGE_LOCATION_CHANGED));
checkForArrival();
}
// Other overrides are empty.
};
if(!arrived)
manager.requestLocationUpdates(provider, updateInterval, 0, listener);
}
/**
* Removes location updates from the LocationListener.
*/
public void removeUpdates() {
if(!(manager == null || listener == null))
manager.removeUpdates(listener);
}
// Another method for "cleaning up" when the user has arrived.
}
And here is my handler:
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case KEY_MESSAGE_LOCATION_CHANGED:
if(myRunnable != null) {
myRunnable.removeUpdates();
handler.postDelayed(myRunnable, updateInterval);
}
break;
}
}
};
Additional info
The whole location updating thing runs in a service.
I have read the doc several times, Google'd the problem, and tried various other workarounds. Nothing quite does it.
I have logged the damn out of this thing, and the only exciting thing to see is a big fat "ignore" to my frequent location requests. All the right methods are called.
Any help will be very much appreciated!
You are completely right, the minimum time 45 seconds is harcoded in Android.
This seems to be a NetworkLocationProvider class source code, when it was still in Android core:
http://www.netmite.com/android/mydroid/frameworks/base/location/java/com/android/internal/location/NetworkLocationProvider.java
Look at the variable:
private static final long MIN_TIME_BETWEEN_WIFI_REPORTS = 45 * 1000; // 45 seconds
And the method:
#Override
public void setMinTime(long minTime) {
if (minTime < MIN_TIME_BETWEEN_WIFI_REPORTS) {
mWifiScanFrequency = MIN_TIME_BETWEEN_WIFI_REPORTS;
} else {
mWifiScanFrequency = minTime;
}
super.setMinTime(minTime);
}
Now NetworkLocationProvider is out of the Android core, you can find it in NetworkLocation.apk in /system/app
You can find an explanation of why is out of the core here:
https://groups.google.com/forum/?fromgroups=#!topic/android-platform/10Yr0r2myGA
But 45 seconds min time seems to still be there.
Look at this NetworkProvider decompilation:
http://android.fjfalcon.com/xt720/miui-trans/apk-decompiled/NetworkLocation/smali/com/google/android/location/NetworkLocationProvider.smali
.line 149
const-wide/32 v4, 0xafc8
iput-wide v4, p0, Lcom/google/android/location/NetworkLocationProvider;->mWifiScanFrequency:J
As you might guess if you convert 0xafc8 to decimal you get 45000 milliseconds
I haven't found an explanation of why 45 seconds. I suppose there will be reasons like avoiding service overloading or other uses they don't want.
In fact, there is a 100 request courtesy limit to Geolocation API:
https://developers.google.com/maps/documentation/business/geolocation/#usage_limits
But they don't seem to respect this rule in Google Maps app. If you open it and you only active network location you can notice that yout location is updated much more frequently than 45 seconds.
I noticed this line suspiciously frequent (33 times a second) in logcat when Google Maps is open:
02-20 17:12:08.204: V/LocationManagerService(1733): getAllProviders
I guess Google Maps is also calling removeUpdates() and requestLocationUpdates() again to obtain a new position.
So I think there is no fix and this is the best you can do if you want to get network locations over one in 45 seconds.
You can set the minTime to any value. However, you will only get an update once a new location is available. The network only updates every 45 sec or so on every phone I own. This seems to be a limitation of the Network Provider. If you want more frequent updates use the GPS provider. Depending on the GPS hardware you should get a maximum update rate around 4Hz.
I was having a similar issue. I put a call to locationManager.requestSingleUpdate() at the end of onLocationChanged() and it forced back to back updates. You could set a delay command then execute requestSingleUpdate, making sure to register the containing locationListener.
I was trying to create a GPS clock but the updates were inconsistent updating anywhere from 1-5 seconds or so. but it might work for another application.