Im using this code for getting the location for my app:
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 200.0f, this);
But when i tried the app in my real android phone it show this location about 80 kilometers away from the location im actualy at.. How would i make this code more accurate.. I want the result to be way more accurate for what im making..
Im using the onLocationChanged to display it at the map.. Here it is:
public void onLocationChanged(Location location) {
if (location != null) {
//Gets users longitude and latitude
lat = location.getLatitude();
lng = location.getLongitude();
//sets the GeoPoint usersLocation equal lat and lng
userLocation = new GeoPoint((int) lat * 1000000, (int) lng * 1000000);
OverlayItem usersLocationIcon = new OverlayItem(userLocation, null, null);
LocationPin myLocationPin = new LocationPin(userIcon, MainActivity.this);
//Removes the previous location
if(previousLocation != null)
mainMap.getOverlays().remove(previousLocation);
myLocationPin.getLocation(usersLocationIcon);
overlayList.add(myLocationPin);
//refresh the map
mainMap.invalidate();
//Making myLocationPin into the previousLocation just to be able to remove it later
previousLocation = myLocationPin;
}
The call requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 200.0f, this); is asking to be updated no more than once every 1000ms when the location from GPS changes by more than 200.0 meters from the last update. If you want finer precision, try lowering these numbers.
However, you shouldn't be off by 80km. Are you testing this outside with a clear view of the sky?
I think the issue is with rounding. You are using new GeoPoint((int) lat * 1000000, (int) lng * 1000000);, but instead do this:
new GeoPoint((int) (lat * 1e6), (int) (lng * 1e6));
The difference is, the double values were converted to integers before the multiplication. This way the multiplication happens afterwards, and so the digits after the decimal point are maintained.
There are 2 possible answers...
You can either ask for fine permission, this uses nearby wi-fi networks along with GPS in order to get a better track on where you are:
http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_FINE_LOCATION
or you might just be getting bad GPS data. Have you tried to restart the phone? Are you getting the correct location in Google Maps?
Hope this helps.
Related
I am trying to calculate the distance between your current location and three markers.
Everything is working fine, but if I change my position the distance is equal to the distance before, I dont get the new coordinates. Here is my code:
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location current = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
latng = String.valueOf(current.getLatitude());
lngon = String.valueOf(current.getLongitude());
Location club = new Location("clubloc");
club.setLatitude(Double.parseDouble(marker_data.get("lat")));
club.setLongitude(Double.parseDouble(marker_data.get("lng")));
double distance = current.distanceTo(club);
distance = distance / 1000;
distance = Math.round(distance * 100);
distance = distance / 100;
TextView dis = (TextView) findViewById(R.id.distance);
dis.setText(String.valueOf(distance) + "KM");
}
So my question is how can I update my coordinates so I always get the right distance?
You are always getting the last known location of the user (using getLastKnownLocation). You are not actively asking for location updates. You can read more about this here.
I have used the following code to check GPS coordinates, but problem is that if i am standing at same place the coordinates changes and distance is anywhere between 4 to 20 mts.
I want to change it only when I have moved min 10 mtrs.
locationManager_gps = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
locationManager_gps.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0,
new MyLocationListener_gps());
class MyLocationListener_gps implements LocationListener {
public void onLocationChanged(Location location) {
clat = location.getLatitude();
clon = location.getLongitude();
if (clat != plat || clon != plon) {
float[] results = new float[3];
Location.distanceBetween(plat, plon, clat, clon, results);
if (flag_gps == 0) {
flag_gps = 1;
} else {
GeoPoint geoPoint = new GeoPoint((int) (clat * 1E6),
(int) (clon * 1E6));
mapView.getController().animateTo(geoPoint);
draw = new MyOverLay(geoPoint);
mapView.getOverlays().add(draw);
dist_mtr += results[0];
}
plat = clat;
plon = clon;
}
}
If I use 50 as min distance between updates then it is working fine. I also tried making it 30 but also data was wrong over a period of 4 km while traveling in car.
Please suggest what I should do.
I've seen this too, when taking several location readings and I haven't moved. You can get variable results with different accuracies.
You could try taking, say, 10 location readings and take the one with the best accuracy and disregard the rest. Then when taking the next reading, make sure it is located at a distance which is twice the accuracy of the previous location. For example, if your first location has an accuracy of, say 16 meters, make sure the next reading is at least 32 meters away from the previous location AND has an accuracy better than 32 meters.
You need to use the minTime and minDistance in combination. You pass zero and zero for both, so the min time between updates will be at least zero seconds and the min distance will be zero. So set minTime to a reasonable time and minDistance to 10 for ten meters.
locationManager_gps.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0,
new MyLocationListener_gps());
There is no magic bullet to solve this... the gps is not 100% accurate and you will always have different readings every time you get a new location update.
You can minimize the issue using a low pass filter for the location values:
clat = plat + (clat-plat) * 0.2; // you should adjust the 0.2 value to the best results
clon = plon + (clon-plon) * 0.2;
....
//your code
....
plat = clat;
plon = clon;
With this the effect of sudden changes to the values will be minimized, which is good for the fake changes in position, but it will also delay the response to the real changes in the positions when the device is moving. You should choose careffuly the value of the constant multiplying (0.2 above) to have the best results.
You can even do better, using a variable instead of a constant, and adjust the value of it based on the accuracy of the loaction update (good accuracy you make the variable close to 1, pour accuracy you make the variable close to 0)
good luck
i am getting data from gps provider using mylocation class. code is this:
MyLocation.LocationResult locationResult = new MyLocation.LocationResult() {
#Override
public void gotLocation(Location location) {
//Got the location!
// for phone
//currentLocation = new GeoPoint((int) (location.getLatitude() * 1000000),
// (int) (location.getLongitude() * 1000000));
// for emulator
currentLocation = new GeoPoint((int) (location.getLatitude()),
(int) (location.getLongitude()));
doSomething();
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
when i use the app in emulator(2.3.3) it shows the correct location without multiplying anything.
but when i use it in a device(4.0) lat and lon need to multiplied with 1000000. i couldn't find why. i don't think its because of the version of android. anyone have any idea?
Because the MapView uses microdegress for its units so you need to multiply by 1e6. Otherwise you show up off the coast of Africa - basically lat long of approximately 0,0
From the documentation on GeoPoint:
An immutable class representing a pair of latitude and longitude, stored as integer numbers of microdegrees.
Don't know why the emulator is working - it shouldn't.
Is there a way to get the accuracy of the fix from MyLocationOverlay? It obviously knows how accurate it is since it draws the circle of the area of how accurate it is. Is there away to get this value?
Thanks
Code from my location listener in one of my apps...
public void onLocationChanged(Location location) {
currentLatitudeE6 = (int) (location.getLatitude() * 1E6);
currentLongitudeE6 = (int) (location.getLongitude() * 1E6);
currentAccuracy = location.getAccuracy();
hasCurrentPosition = true;
gpsMessage = "GPS Tracking";
updateMap();
}
Implement Location Listener by locationManager.requestLocationUpdates method, check following link:
http://hejp.co.uk/android/android-gps-example/
I am facing a problem with the google map search. I have mad a app through which i can see a location in google map on my emulator which is set in the code as:
int lat = (int)(22.3666667*1000000);
int lng = (int)(91.8000000*1000000);
GeoPoint pt = new GeoPoint(lat,lng);
This works fine.
Now i want to search a location dynamically i.e. i have a editbox(Location_For_Search) and a button(Find_Location_Button). So when i write some location in editbox and press the button then it will show the location in google map with a marker on location. How can i do this?
Please any one help me.
With best wishes
Md. Fazla Rabbi
Use the geocoder:
Geocoder geo = new Geocoder(this);
List<Address> addr;
try
{
addr = coder.getFromLocationName(yourEditTextaddr, 10);
Address loc = addr.get(0);
loc.getLatitude();
loc.getLongitude();
point = new GeoPoint((int) (loc.getLatitude() * 1E6),
(int) (loc.getLongitude() * 1E6));
return point;
}