Tracking distance with "distanceBetween" is wrong and driving me nuts - android

I have trouble with the tracking of a driven distance.
I tried it like in this article: Source-Code is completely also there
The SUM of the driven distance is not the real driven distance that is displayed in my car.
After 2-3 km, I have a difference between my displayed distance in my car and the app of 200-800 meters. In this short distance :o)
What I also recognized is that the distance, e.g. while driving curves, is decrementing.
I have also tried several values for minTime and minDistance for the listener, but no success.
What I am doing wrong?
When I use the "MyTracks" app, the driven distance is caculated really, really fine and correct.
I only need a way to sum the completely driven way from start to end, without displaying it in google maps. Is this really so complicated?
kind regards
Frank
OK, the interesting part of the code:
public void startListening(final Activity activity)
{
if (locationManager == null)
{
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
}
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
final String bestProvider = locationManager.getBestProvider(criteria, true);
if (bestProvider != null && bestProvider.length() > 0)
{
locationManager.requestLocationUpdates(bestProvider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
else
{
final List<String> providers = locationManager.getProviders(true);
for (final String provider : providers)
{
locationManager.requestLocationUpdates(provider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
}
}
and:
private double calcGeoDistance(final double lat1, final double lon1, final double lat2, final double lon2)
{
double distance = 0.0;
try
{
final float[] results = new float[3];
Location.distanceBetween(lat1, lon1, lat2, lon2, results);
distance = results[0];
}
catch (final Exception ex)
{
distance = 0.0;
}
return distance;
}
and:
private void updateMeasurement(){
double distance = calcGeoDistance(startLat,startLon,currentLat,currentLon) * multipliers[unitindex];
String distanceText = "" + RoundDecimal(distance,2) + " " + unitstrings[unitindex];
((TextView)findViewById(R.id.distance)).setText(distanceText);
}
and:
public double RoundDecimal(double value, int decimalPlace)
{
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(decimalPlace, 6);
return bd.doubleValue();
}
Ohhh, and as I am writing this down it seems that the distance is caculated between the start point and the current point. Not between the last two measurements with the sum of all values, right?

With the Criteria that you specify, you're likely to get innacurate locations. Increase the power requirement. Also, pay attention to the name of the provider being returned. If you want accuracy, then you're going to want the GPS provider.
See the following link for more information:
I keep getting an inaccurate location in Android

Related

Finding out if a phone's current longitude and latitude is within the radius of a gps location

I'm hoping someone can help with this.
I've seen many posts and answers but none of them seem to address my specific problem, but if I've missed one, I apologise in advance.
I'm building a small app that stores a phones current longitude and latitude as doubles. This is done via android's LocationManager
#TargetApi(23)
private void initLocationService(Context context) {
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
this.longitude = 0.0;
this.latitude = 0.0;
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// Get GPS and network status
this.isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
this.isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (forceNetwork) isGPSEnabled = false;
if (!isNetworkEnabled && !isGPSEnabled) {
// cannot get location
this.locationServiceAvailable = false;
}
else
{
this.locationServiceAvailable = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
updateCoordinates();
}
}//end if
if (isGPSEnabled) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
updateCoordinates();
}
}
}
} catch (Exception ex) {
}
}
public void updateCoordinates()
{
longitude = location.getLongitude();
latitude = location.getLatitude();
}
I've got a set of longitude and latitude coordinates hardcoded into the app, but need a way to work out if my user is within a specific metre radius of a hardcoded point.
I'm using just the Android API's for the project and can't deviate from that.
I've already found out how to convert the longitude and latitude from degrees to metres:
public double longOffset(int offsetX, double lon){
double longoff = offsetX / earthRadius;
return lon + longoff * 180 / Math.PI;
}
public double latOffset(int offsetY, double lat){
double latoff = offsetY / (earthRadius * cos(Math.PI*lat/180));
return lat + latoff * 180 / Math.PI;
}
But I admit to being stumped on the rest.
I'm wondering if creating a small bounding box around the longitude and latitude and then using a method similar to the one shown here:
http://www.sanfoundry.com/java-program-check-whether-given-point-lies-given-polygon/
I'm getting to the point now where i'm going crosseyed so any help would be appreciated.
Like #EugenPechanec says, you can use SphericalUtil.computeDistanceBetween() from Google Maps Android API utility library . Something like this:
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
LatLng positionLatLng = new LatLng(latitude, longitude);
// sample hardcoded point.
LatLng specificPointLatLang = new LatLng(1.333434, 1.3333);
// Returns the distance between two LatLngs, in meters.
double distance = SphericalUtil.computeDistanceBetween(positionLatLng, specificPointLatLang);

How to get always the newest current Coordinates

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.

How to get accurate GPS Coordinates Android LocationServices

I am just trying to figure out what can I do to ensure I get precise GPS Coordinates from the mobile device. When I add the distances together, I get a crazy reading that I have gone 8m when the phone has not moved from my table. I do not know if it is because of the way I have set up my LocationRequest. I was reading on google something about GPS coordinates being 68% accurate, and some readings may fall out of the 68%... perhaps I should do something to remove the inaccurate readings??
Here is the location request I have created, so I can receive the location updates:
private void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(2000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//Some other code below which checks location settings
}
This is my onLocationChanged... this is where I get updates of the new location, and then calculate the distance between the two points:
#Override
public void onLocationChanged(Location location) {
//For the first location update, we will assume this is the starting point
if (currentLocation == null) {
currentLocation = location;
}
float distance = 0L;
double height = 0;
double speed = 0;
height = location.getAltitude();
if (runStarted && !runPaused) {
locationsList.add(location); //This adds the current location to the list
runnerLocations.add(location); //This adds the current route the runner is running (without pauses)
} else {
locationsList.add(location);
}
//Calculate the distance from the last recorded gps point
if (currentLocation != null && runStarted && !runPaused){
distance = currentLocation.distanceTo(location);
}
currentLocation = location;
//move the map view to the user's current location, regardless of their running state (paused or run)
mapObject.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 18));
if (runStarted && !runPaused) {
if (location.getSpeed() > 0) {
speed = location.getSpeed() * 3.6;// convert m/sec to km/h
}
DecimalFormat format = new DecimalFormat("###.##");
speed = Double.valueOf(format.format(speed));
recordedSpeeds.add(speed);
totalDistance = totalDistance + distance;
updateUI(speed, location, distance);
if (height > 0) {
height = Double.valueOf(format.format(height));
}
calculateCurrentCaloriesBurnt(height, speed);
}
}
I was thinking of calculating the distances manually, with some formula. What else can I try, to get accurate distance calculations?

Running gps android

Trying to create a running gps in android, using this code to calculate the distance between two points every second (at least that's what I think it's doing):
gps = new GPSTracker(AndroidGPSTrackingActivity.this);
// check if GPS enabled
if (gps.canGetLocation()) {
final Handler h = new Handler();
final int delay = 1000; //milliseconds
h.postDelayed(new Runnable() {
public void run() {
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Location locationA = new Location("point A");
final Location locationB = new Location("point B");
locationA.setLatitude(latitude);
locationA.setLongitude(longitude);
Timer t = new Timer();
h.postDelayed(new Runnable() {
public void run() {
double latitude1 = gps.getLatitude();
double longitude2 = gps.getLongitude();
locationB.setLatitude(latitude1);
locationB.setLongitude(longitude2);
}
}, delay);
float distance = locationA.distanceTo(locationB);
finalDistance[0] = (finalDistance[0] + distance);
displayDistance.setText(String.valueOf(finalDistance[0]));
h.postDelayed(this, delay);
}
}, delay);
The distance changes more or less by the same increment whether I'm walking or not walking.
The distance I get is also a weird value, e.g.: 6.47875890357E9
My questions: 1)What unit is this distance in?
2)Am I getting some random gobbledigook because of crap programming skills?
1) The units are meters (see distanceTo()).
2) Yes. But like all programmers, you're still learning, so to be more helpful I won't just leave it there! The reason you are getting a huge distance is because your code is getting the distance between locationA and locationB, and you haven't set locationB at the time you execute the line:
float distance = locationA.distanceTo(locationB);
So you're getting the distance between locationA and lat/long 0,0.
You're only setting the latitude and longitude of locationB in your Runnable which will be executed after distance has been set. So, you probably need to move your distance calculation and the code that outputs it to within your Runnable that sets the latitude and longitude for locationB. You'll also have to make locationA final to do that.

find the nearest location among locations from our location

I am developing an Android application.
I am getting a list of latitudes and longitudes from the server.
I have to arrange those values based on my location. I mean the nearest latitude/longitude first and then the next one etc.
I have my latitude and longitude and the list of latitude and longitudes. How can I find the nearest one?
This might not be the best way but it works :)
public static final double PI = 3.14159265;
public static final double deg2radians = PI/180.0;
public static final double miles = 0.000621371192;
public static final double kms = 0.001;
public static double getDistance(double latitude1, double longitude1, double latitude2,double longitude2) {
double distance;
Location locationA = new Location("point A");
locationA.setLatitude(latitude1);
locationA.setLongitude(longitude1);
Location locationB = new Location("point B");
locationB.setLatitude(latitude2);
locationB.setLongitude(longitude2);
distance = locationA.distanceTo(locationB);
double radd = distance * kms;
return radd;
}
pseudo code :
location.distanceTo(locFromServer);
and for the sorting
Colection.sort(listOfLocations;new Comparator(){
compareTo(){
// location.distanceTo(locFromServer)
}
}
You can simply calculate the distances of the user's position to the downloaded locations, and select the smallest one.
Have a look here: Quicker way to calculate geographic distance between two points.

Categories

Resources