2

I get the GPS location 3 way like Map.getMyLocation().getLatitude(), locationManager and mGoogleApiClient. but these are not helped for me for calculating distance every 15 sec. problem is location latitude and longitude are not accurately i.e I am walking like 1-2 meter with using these way distance calculation. calculating distance is 400 m-600 meter sometimes show 1 km also. GPS location variate like 20 meters to 600 meters. Please give some better idea about how to get my location heavy accuracy with calculating distance every 15 sec in android.

this is my code

//get current location
try {
    locationManager = (LocationManager) getApplicationContext()
            .getSystemService(LOCATION_SERVICE);

    // getting GPS status
    isGPSEnabled = locationManager
            .isProviderEnabled(LocationManager.GPS_PROVIDER);

    // getting network status
    isNetworkEnabled = locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    if (!isGPSEnabled && !isNetworkEnabled) {
        // no network provider is enabled
    } else {
        canGetLocation = true;
        // First get location from Network Provider
        if (isNetworkEnabled) {
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            Log.d("Network", "Network");
            if (locationManager != null) {

                location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (location != null) {
                    old_latitude = location.getLatitude();
                    old_longitude = location.getLongitude();
                }
            }
        }
        // if GPS Enabled get lat/long using GPS Services
        if (isGPSEnabled) {
            if (location == null) {
                locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (location != null) {
                        old_latitude = location.getLatitude();
                        old_longitude = location.getLongitude();

                        Log.d("GPS Enabled", "GPS Enabled");
                    }
                }
            }
        }

    }
    //  Toast.makeText(this, "Current location"+current_latitude+","+current_longitude , Toast.LENGTH_LONG).show();
} catch (Exception e) {
    e.printStackTrace();
}

       /* GPSTracker gpsTracker = new GPSTracker(Activity_Map_Advance_Tracking.this);

        if (gpsTracker.getIsGPSTrackingEnabled()) {
            old_latitude=gpsTracker.latitude;
           old_longitude=gpsTracker.longitude;
        }*/
old_latitude = mMap.getMyLocation().getLatitude();
old_longitude = mMap.getMyLocation().getLongitude();

if (trip_status.equals("trip"))
    ha.postDelayed(new Runnable() {

        @Override
        public void run() {


            //get current location
            try {
                locationManager = (LocationManager) getApplicationContext()
                        .getSystemService(LOCATION_SERVICE);

                // getting GPS status
                isGPSEnabled = locationManager
                        .isProviderEnabled(LocationManager.GPS_PROVIDER);

                // getting network status
                isNetworkEnabled = locationManager
                        .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                if (!isGPSEnabled && !isNetworkEnabled) {
                    // no network provider is enabled
                } else {
                    canGetLocation = true;
                    // First get location from Network Provider
                    if (isNetworkEnabled) {
                        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

                        Log.d("Network", "Network");
                        if (locationManager != null) {

                            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                            if (location != null) {
                                new_latitude = location.getLatitude();
                                new_longitude = location.getLongitude();
                            }
                        }
                    }
                    // if GPS Enabled get lat/long using GPS Services
                    if (isGPSEnabled) {
                        if (location == null) {
                            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


                            if (locationManager != null) {
                                location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                if (location != null) {
                                    new_latitude = location.getLatitude();
                                    new_longitude = location.getLongitude();

                                    Log.d("GPS Enabled", "GPS Enabled");
                                }
                            }
                        }
                    }

                }
                //  Toast.makeText(this, "Current location"+current_latitude+","+current_longitude , Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
            // check if GPS enabled
               /* GPSTracker gpsTracker = new GPSTracker(Activity_Map_Advance_Tracking.this);

                if (gpsTracker.getIsGPSTrackingEnabled()) {
                    new_latitude = gpsTracker.latitude;
                    new_longitude =gpsTracker.longitude;
                }*/
            new_latitude = mMap.getMyLocation().getLatitude();
            new_longitude = mMap.getMyLocation().getLongitude();


            double GPS_jump = 0.000100;

            if (Math.abs(old_latitude - new_latitude) < GPS_jump && Math.abs(old_longitude - new_longitude) < GPS_jump) {
                waiting_sec = waiting_sec + 15;
                if (waiting_sec >= (waiting_time * 60)) {
                    if (wait == 0) {
                        waitng_charge = (waiting_amnt_per_sec * waiting_sec) + waitng_charge;
                        wait = 15;
                        //waiting_sec=0;
                    } else {
                        waitng_charge = (waiting_amnt_per_sec * wait) + waitng_charge;
                    }
                }

                // total_distance=meterDistanceBetweenPoints(13.020876, 80.222541,13.021301, 80.222881)+total_distance;
                // client_info.setText("TOTAL DISTANCE:"+total_distance/1000);
                System.out.println("vehicle not move" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude));
                Toast.makeText(Activity_Map_Advance_Tracking.this, "vehicle not move" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();


                // assuming doubles are equals
            } else {

                System.out.println("vehicle moved" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude));
                if ((waiting_sec) >= (waiting_time * 60)) {
                    waitng_charge = waiting_amnt_per_sec + waitng_charge;
                }
                total_distance = meterDistanceBetweenPoints(old_latitude, old_longitude, new_latitude, new_longitude) + total_distance;
                waiting_sec = 0;
                wait = 0;

                Toast.makeText(Activity_Map_Advance_Tracking.this, "vehicle moved" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
                Toast.makeText(Activity_Map_Advance_Tracking.this, "****TOTAL DISTANCE*****->" + total_distance, Toast.LENGTH_LONG).show();
                client_info.setText("TOTAL DISTANCE:" + total_distance);
            }


            delay_sec = delay_sec + 15;
            System.out.println("After " + delay_sec + " sec \n waiting sec" + waiting_sec + " sec\n waitng charge" + waitng_charge + "rs \n currunt lat and lng" + new_latitude + " , " + new_longitude + "" +
                    "\n___old lat lng" + old_latitude + " , " + old_longitude);


            Toast.makeText(Activity_Map_Advance_Tracking.this, "After " + delay_sec + " sec \n waiting sec" + waiting_sec + " sec\n waitng charge" + waitng_charge + "rs \n currunt lat and lng" + new_latitude + " , " + new_longitude + "" +
                    "\n___old lat lng" + old_latitude + " , " + old_longitude + ", \ntotal distance: " + total_distance, Toast.LENGTH_LONG).show();


            old_latitude = new_latitude;
            old_longitude = new_longitude;

            //call function
            ha.postDelayed(this, 15000);
        }
    }, 15000);

this is my distance calculation method but this method is not issue

 private float meterDistanceBetweenPoints(double lat_a, double lng_a, double lat_b, double lng_b) {
    /*Location locationA = new Location("point A");

    locationA.setLatitude(lat_a);
    locationA.setLongitude(lng_a);

    Location locationB = new Location("point B");

    locationB.setLatitude(lat_b);
    locationB.setLongitude(lng_b);

    float distance = locationA.distanceTo(locationB);*/
    double earthRadius = 6371000; //meters
    double dLat = Math.toRadians(lat_b - lat_a);
    double dLng = Math.toRadians(lng_b - lng_a);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(Math.toRadians(lat_a)) * Math.cos(Math.toRadians(lat_b)) *
                    Math.sin(dLng / 2) * Math.sin(dLng / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    float dist = (float) (earthRadius * c);


    System.out.println("**********this is distance calculation**********" + dist);
    return dist;
}
Akash pasupathi
  • 304
  • 1
  • 14
  • 2
    Why are you using Handler to get Location update after 15 sec?! You can get location update after specific time or distance by LocationManager and FusedLocationApi – tahsinRupam Mar 06 '17 at 07:36
  • @tahsinRupam i also try LocationManager or FusedLocationApi with using mLocationRequest.setInterval(INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); but no use. problem is location heavy jump – Akash pasupathi Mar 06 '17 at 07:39
  • And it didn't work ? What are the problems you are facing? – tahsinRupam Mar 06 '17 at 07:45
  • location deference like 200 m to 600 m. for GPS location jump – Akash pasupathi Mar 06 '17 at 07:47
  • Under bad receiving conditions this is quite normal. Even under optimal conditions 10m is the best you can hope for. – Henry Mar 06 '17 at 07:55
  • but i checked another distance calculation app like https://play.google.com/store/apps/details?id=com.firitools.firitools.kmhfiritools&hl=en on there.but it is work good compared to my app. – Akash pasupathi Mar 06 '17 at 08:00
  • Using only GPS for non-military purpose has an imposed accuracy threshold. http://gis.stackexchange.com/a/43657 – Sangharsh Mar 06 '17 at 08:00
  • @Sangharsh i dint understand about that please give more details with example – Akash pasupathi Mar 06 '17 at 08:10
  • @Akashpasupathi I've added an easy solution. You may check. – tahsinRupam Mar 06 '17 at 08:12
  • GPS doesn't give better than 5-10 meter accuracy (for civilian use). So, if you are walking / travelling at slow speed and changing direction frequently distance using GPS will have significant error. – Sangharsh Mar 06 '17 at 08:30

4 Answers4

3

You can use requestLocation update for start getting update of location:

mylistener = new MyLocationListener();
locationManager.requestLocationUpdates(provider, 150000, 1, mylistener);

Here you will get update after every 15 secs and 1 meter location change:

When locationmanager gets update of location it calls the onLocationChanged() method. You will get updated location there.

private class MyLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location location) {
    }
         //Do your code with this updated location
}

You can set Criteria location gathering. If you want to get accurate location I suggest you to use only GPS_PROVIDER. Remember GPS does not work properly inside the house though.

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setPowerRequirement(Criteria.POWER_HIGH);
    provider = locationManager.getBestProvider(criteria, true);
    previouslocation = locationManager.getLastKnownLocation(provider);

Declare globally -

 float distanceInMeters = 0; 

Add the distance in onLocationChanged():

public void onLocationChanged(Location location) {
      distanceInMeters += previousLocation.distanceTo(location);  
      Toast.makeText(YourActivity.this, "Distance" + distanceInMeters,Toast.LENGTH_SHORT).show();    // Showing the distance in meter
      previousLocation = location;
   }

NOTICE: I've changed the first location value to previousLocation for avoiding confusion.

tahsinRupam
  • 6,325
  • 1
  • 18
  • 34
  • Any time mate ;) – tahsinRupam Mar 06 '17 at 08:16
  • @tasinRupan this is not work for me.again same issue like location jump. jump like .012 to .02 – Akash pasupathi Mar 06 '17 at 10:08
  • 1
    Are you getting distance in kilometers ? Whar is the amount of displacement from actual distance ? Even GPS can vary ~20 feet more or less. check this article - https://developerlife.com/2010/10/20/gps/ – tahsinRupam Mar 06 '17 at 10:16
  • @tasinRupan bro i create sample distance calculate with using your above code but same issue please check this http://stackoverflow.com/a/42625593/7399521 thank you – Akash pasupathi Mar 06 '17 at 12:26
  • Remove this line from onLocationChanged() : location = locationManager.getLastKnownLocation(provider); And add your updated code to your question (edit the previous one) – tahsinRupam Mar 06 '17 at 12:33
  • bro i updated but why i remove location = locationManager.getLastKnownLocation(provider); . because that getting refresh new location every 15 sec. thets y add it. – Akash pasupathi Mar 06 '17 at 12:40
  • Yeah don't you want the new location ? This is the most important part for distance measurement. Just compare with previous location, get the difference and add to a variable called distance. Thats how you get the distance. I can add the code for distance measurement If you like. – tahsinRupam Mar 06 '17 at 12:47
  • ok bro i was confused to this get that distance calculation. please give idea and example. – Akash pasupathi Mar 06 '17 at 12:52
  • I've added the distance counting. Please check. – tahsinRupam Mar 06 '17 at 13:06
2

please check this using like

   criteria.setPowerRequirement(Criteria.POWER_HIGH);

MainActivity.java

public class MainActivity extends AppCompatActivity {

LocationManager locationManager;
Criteria criteria;
String provider;
Location location;
double old_latitude; // latitude
double old_longitude; // longitude
TextView distance;
double new_latitude; // latitude
double new_longitude; // longitude
float total_distance = 0.0f;
String details;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    distance = (TextView) findViewById(R.id.distance);

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setPowerRequirement(Criteria.POWER_HIGH);
    provider = locationManager.getBestProvider(criteria, true);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    location = locationManager.getLastKnownLocation(provider);

    try {
        old_latitude = location.getLatitude();
        old_longitude = location.getLongitude();
    } catch (Exception e) {

    }

    locationManager.requestLocationUpdates(provider, 15000, 1, new LocationListener() {


        @Override
        public void onLocationChanged(Location location) {
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            location = locationManager.getLastKnownLocation(provider);
            new_latitude = location.getLatitude();
            new_longitude = location.getLongitude();

            total_distance = meterDistanceBetweenPoints(old_latitude, old_longitude, new_latitude, new_longitude) + total_distance;

            if (details == null) {
                details = "current location:" + new_latitude + ", " + new_longitude;
                details = details + "\n" + "old location:" + old_latitude + ", " + old_longitude;
                details = details + "\n" + "\n" + "total distance:" + total_distance + " m";
                details = details + "\n" + "----------------------------------------------" + "\n";
            } else {

                details = details + "\n" + "current location:" + new_latitude + ", " + new_longitude;
                details = details + "\n" + "old location:" + old_latitude + ", " + old_longitude;
                details = details + "\n" + "\n" + "total distance:" + total_distance + " m";
                details = details + "\n" + "----------------------------------------------" + "\n";
            }

            distance.setText(details);

            old_latitude = new_latitude;
            old_longitude = new_longitude;

            System.out.println("**********this is LocationChanged**********" + 15000);
            Toast.makeText(MainActivity.this, "current location" + new_latitude + new_longitude, Toast.LENGTH_LONG).show();
            Toast.makeText(MainActivity.this, "old location" + old_latitude + old_longitude, Toast.LENGTH_LONG).show();
            Toast.makeText(MainActivity.this, "LocationChanged" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();

        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {
            System.out.println("**********this is StatusChanged**********" + 15000);
            Toast.makeText(MainActivity.this, "StatusChanged" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();

        }

        @Override
        public void onProviderEnabled(String s) {
            System.out.println("**********this is ProviderEnabled**********" + 15000);
            Toast.makeText(MainActivity.this, "ProviderDisabled" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();

        }

        @Override
        public void onProviderDisabled(String s) {
            System.out.println("**********this is ProviderDisabled**********" + 15000);
            Toast.makeText(MainActivity.this, "ProviderDisabled" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();

        }
    });


    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
private float meterDistanceBetweenPoints(double lat_a, double lng_a, double lat_b, double lng_b) {
    double earthRadius = 6371000; //meters
    double dLat = Math.toRadians(lat_b - lat_a);
    double dLng = Math.toRadians(lng_b - lng_a);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(Math.toRadians(lat_a)) * Math.cos(Math.toRadians(lat_b)) *
                    Math.sin(dLng / 2) * Math.sin(dLng / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    float dist = (float) (earthRadius * c);
    Toast.makeText(MainActivity.this, "calculated distance" + dist + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
    System.out.println("**********this is distance calculation**********" + dist);
    return dist;
}}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.rmadeandroid.lcation_change_listioner.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_main" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    app:srcCompat="@android:drawable/ic_dialog_email" /</android.support.design.widget.CoordinatorLayout>

content_main.xml

<?xml version="1.0" encoding="utf-8"?><ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.rmadeandroid.lcation_change_listioner.MainActivity"
tools:showIn="@layout/activity_main"><RelativeLayout
android:id="@+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"><TextView
    android:id="@+id/distance"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="device not move" /></RelativeLayout></ScrollView>

permission in manifest

 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

output

my output

Akash pasupathi
  • 304
  • 1
  • 14
0

As someone in the comments section posted, use LocationManager /FusedLocationApi. What you can do extra is:

  1. Even though you need the location every 15 seconds, get it at smaller intervals or maybe continuous and calculate then. This will put strain on the device's battery.
  2. If the new location that you get is at a pretty big distance from your last one, ignore it. Some devices may return bad values (had a Nexus5 that would work now and the next second show me 4-5 kms away).
  3. If battery will be an issue, set the interval to 15 seconds, maybe with PRIORITY_BALANCED_POWER_ACCURACY, but make sure you have a fallback. If the distance between two locations is too big or the accuracy of the reading is bad, ignore it/request another location.
Adrian Coman
  • 1,536
  • 17
  • 30
0

In one answer, the code:

distanceInMeters += previousLocation.distanceTo(location);

is good but I suggest - unless someone finds it problematic, to simply use:

locationManager.requestLocationUpdates(provider, 0, DISTANCE, mylistener); 

and accumulate the DISTANCE (provided it's a relatively small DISTANCE). Sorry I couldn't put that in comments because they removed a lot points.

Edits: but distanceInMeters += previousLocation.distanceTo(location) is more accurate than what I suggested above.