Android getting element from ArrayList<LatLng>() - android

I have an array list, ArrayList(), which is used to save lat and lng. I want to get the element inside this array, in order to calculate the distance.
private void whereAmI(){
Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
updateWithNewLocation(location);
//GPS Listener
manager.addGpsStatusListener(gpsListener);
//Location Listener
int minTime = 0;//ms
int minDist = 0;//meter
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDist, locationListener);
}
GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
#Override
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_STARTED:
Log.d("x=", "GPS_EVENT_STARTED");
Toast.makeText(MapsActivity.this, "GPS_EVENT_STARTED", Toast.LENGTH_SHORT).show();
break;
case GpsStatus.GPS_EVENT_STOPPED:
Log.d("x=", "GPS_EVENT_STOPPED");
Toast.makeText(MapsActivity.this, "GPS_EVENT_STOPPED", Toast.LENGTH_SHORT).show();
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
Log.d("x=", "GPS_EVENT_FIRST_FIX");
Toast.makeText(MapsActivity.this, "GPS_EVENT_FIRST_FIX", Toast.LENGTH_SHORT).show();
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
Log.d("x=", "GPS_EVENT_SATELLITE_STATUS");
break;
}
}
};
LocationListener locationListener = new LocationListener(){
#Override
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
#Override
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
switch (status) {
case LocationProvider.OUT_OF_SERVICE:
Log.v("x=", "Status Changed: Out of Service");
Toast.makeText(MapsActivity.this, "Status Changed: Out of Service", Toast.LENGTH_SHORT).show();
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
Log.v("x=", "Status Changed: Temporarily Unavailable");
Toast.makeText(MapsActivity.this, "Status Changed: Temporarily Unavailable", Toast.LENGTH_SHORT).show();
break;
case LocationProvider.AVAILABLE:
Log.v("x=", "Status Changed: Available");
Toast.makeText(MapsActivity.this, "Status Changed: Available", Toast.LENGTH_SHORT).show();
break;
}
}
};
private void showMarkerMe(double lat, double lng){
if (markerMe != null) {
markerMe.remove();
}
MarkerOptions markerOpt = new MarkerOptions();
markerOpt.position(new LatLng(lat, lng));
markerOpt.title("I am here!");
markerMe = mMap.addMarker(markerOpt);
//Toast.makeText(this, "lat:" + lat + ",lng:" + lng, Toast.LENGTH_SHORT).show();
}
private void cameraFocusOnMe(double lat, double lng){
CameraPosition camPosition = new CameraPosition.Builder()
.target(new LatLng(lat, lng))
.zoom(16)
.build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPosition));
}
private void trackToMe(double lat, double lng){
if (traceOfMe == null) {
traceOfMe = new ArrayList<LatLng>();
}
traceOfMe.add(new LatLng(lat, lng));
calculateDistance(traceOfMe);
PolylineOptions polylineOpt = new PolylineOptions();
for (LatLng latlng : traceOfMe) {
polylineOpt.add(latlng);
}
polylineOpt.color(Color.RED);
Polyline line = mMap.addPolyline(polylineOpt);
line.setWidth(10);
}
private void calculateDistance(ArrayList<LatLng> points) {
for (int i =0; i < points.size() -1; i++) {
LatLng pointA = points.get(i);
LatLng pointB = points.get(i + 1);
float[] results = new float[3];
Location.distanceBetween (pointA.latitude, pointA.longitude, pointB.latitude, pointB.longitude, results);
totalD += results[0];
}
}
private void updateWithNewLocation(Location location) {
String where = "";
if (location != null) {
double lng = location.getLongitude();
double lat = location.getLatitude();
float speed = location.getSpeed();
long time = location.getTime();
String timeString = getTimeString(time);
speedList.add(""+ speed);
where = "Lng: " + lng +
" Lat: " + lat +
" Speed: " + speed +
"\nTime: " + timeString +
" Provider: " + "gps" +
" Distance: " + totalD ;
showMarkerMe(lat, lng);
cameraFocusOnMe(lat, lng);
trackToMe(lat, lng);
}else{
where = "No location found.";
}
txt.setText(where);
}
I use the codes above to track the route, i want to calculate the total distance, using distanceBetween, but i don't know how to do it.

You have to go through all the point of your trajectory.
And call distanceBetween for each segment of your path.
The distanceBetween method take a float[] paramters and store the results in it.
results[0] = the distance between the two points in meters.
results1 = the initial bearing (Seems it is not always set)
results[2] = the final bearing (Seems it is not always set)
For more information see the documentation there
So Something like that should do the job
private float calculateDistance(ArrayList<LatLng> points) {
float totalDistance = 0f;
for (int i =0; i < points.size() -1; i++ {
LatLng pointA = points.get(i);
LatLng pointB = points.get(i + 1);
float[] results = new float[3];
Location.distanceBetween (pointA.latitude, pointA.longitude, pointB.latitude, pointB.longitude, results);
totalDistance += results[0];
}
return totalDistance;
}
Here is a more optimised solution :
In your activiy you store two variables
LatLng previousLocation
float totalDistance
then in your onLocationChanged method. You call the addToDistance method like that
// Goes inside your Location listener
#Override
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
addToDistance(location);
}
// Goes inside your activity
public void addToDistance(LatLng newPoint) {
if (previousLocation != null) {
float[] results = new float[3];
Location.distanceBetween (previousLocation.latitude, previousLocation.longitude, newPoint.latitude, newPoint.longitude, results);
totalDistance += results[0];
}
previousLocation = newPoint;
}

Related

draw line on google map on button click

i have Array list of LatLong which i got from database, i need to draw polyline on map but one by one(after some interval) and also want to move the marker.
here is my code.
if (v.getId() == R.id.btnPlayBack) {
googleMap.clear();
mStopHandler = true;
for (int i = 0; i < movementLine.size(); i++) {
marker.remove();
LatLng latlng = new LatLng(movementLine.get(i).latitude, movementLine.get(i).longitude);
marker = googleMap.addMarker(new MarkerOptions()
.position(latlng)
.title("Position")
.snippet("Latitude:" + latlng.latitude + ", Longitude:" + latlng.longitude));
googleMap.addPolyline(new PolylineOptions()
.add(new LatLng(latlng.latitude, latlng.longitude)));
animateMarker(googleMap, marker, new LatLng(latlng.latitude, latlng.longitude), false);
}
}
private static void animateMarker(GoogleMap googleMap, final Marker marker, final LatLng toPosition,
final boolean hideMarker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = googleMap.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 500;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
double lng = t * toPosition.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
marker.setVisible(false);
} else {
marker.setVisible(true);
}
}
}
});
}
but its not working is there i did anything wrong?
i want show movement of marker with polyline.
here when i use
googleMap.addPolyline(new PolylineOptions()
.addAll(movementLine));
it will draw route with all point from array list.but i need show one by one.
please help me out..
Just create one like here:
PolylineOptions options = new PolylineOptions().width(5).color(Color.RED).geodesic(true);
for (int z = 0; z < list.size(); z++) {
LatLng point = list.get(z);
options.add(point);
}
line = myMap.addPolyline(options);
I'm also not sure you should use geodesic
if (v.getId() == R.id.btnPlayBack) {
final Handler handler = new Handler();
timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
//callToFetchRecords();
try {
PlayBack();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 2000); //execute in every 2 sec
}
}
private void PlayBack() {
LatLng latlng = new LatLng(movementLine.get(pos).latitude, movementLine.get(pos).longitude);
marker = googleMap.addMarker(new MarkerOptions()
.position(latlng)
.title("Staring Point")
.snippet("Latitude:" + latlng.latitude + ", Longitude:" + latlng.longitude));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlng, 19));
options.add(latlng);
RoutePolyline = googleMap.addPolyline(options);
animateMarker(googleMap, marker, latlng, false);
pos++; }

How to calculate distance every 15 sec with using GPS heavy accuracy

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;
}
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.
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
As someone in the comments section posted, use LocationManager /FusedLocationApi. What you can do extra is:
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.
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).
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.
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.

Compass not working properly in osmdroid

I am using a plasio turbo x to test my osmdroid sample. I am also testing using a moto g. In moto g the map rotation which is according to the compass head up is working fine, but in plasio one the compass starts to spin and map also spins, they don't get stable. You can see the logcat here(it is very big, stackoverflow not letting me add it here).
Following is my class in which I have used compass:
public class MainActivity extends FragmentActivity implements LocationListener, IOrientationConsumer,MapEventsReceiver {
private CompassOverlay mCompassOverlay = null;
private MyLocationNewOverlay mLocationOverlay;
IOrientationProvider compass = null;
int deviceOrientation = 0;
MapView mMapView;
float gpsspeed;
float gpsbearing;
float lat = 0;
float lon = 0;
float alt = 0;
long timeOfFix = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
final double lat1 = Double.parseDouble(intent.getStringExtra("lat1"));
final double long1 = Double.parseDouble(intent.getStringExtra("long1"));
final double lat2 = 25.633;
final double long2 = 71.094;
//important! set your user agent to prevent getting banned from the osm servers
org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants.setUserAgentValue(BuildConfig.APPLICATION_ID);
mMapView = (MapView) findViewById(R.id.map);
mMapView.setTileSource(TileSourceFactory.MAPNIK);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
mMapView);
mCompassOverlay.enableCompass();
mMapView.getOverlays().add(this.mCompassOverlay);
addOverlays();
GeoPoint startPoint = new GeoPoint(lat1, long1);
IMapController mapController = mMapView.getController();
mapController.setZoom(9);
mapController.setCenter(startPoint);
Marker startMarker = new Marker(mMapView);
startMarker.setPosition(startPoint);
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
mMapView.getOverlays().add(startMarker);
RoadManager roadManager = new OSRMRoadManager(this);
ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
waypoints.add(startPoint);
GeoPoint endPoint = new GeoPoint(lat2, long2);
Marker endMarker = new Marker(mMapView);
endMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
mMapView.getOverlays().add(endMarker);
waypoints.add(endPoint);
Road road = roadManager.getRoad(waypoints);
Polyline roadOverlay = RoadManager.buildRoadOverlay(road);
mMapView.getOverlays().add(roadOverlay);
mMapView.invalidate();
}
public void addOverlays() {
mLocationOverlay = new MyLocationNewOverlay(mMapView);
mLocationOverlay.setEnableAutoStop(false);
mLocationOverlay.enableFollowLocation();
mLocationOverlay.enableMyLocation();
this.mMapView.getOverlayManager().add(mLocationOverlay);
mMapView.setBuiltInZoomControls(true);
mMapView.setMultiTouchControls(true);
mMapView.setTilesScaledToDpi(true);
}
#Override
protected void onResume() {
super.onResume();
//lock the device in current screen orientation
int orientation;
int rotation = ((WindowManager) this.getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
this.deviceOrientation = 0;
break;
case Surface.ROTATION_90:
this.deviceOrientation = 90;
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
break;
case Surface.ROTATION_180:
this.deviceOrientation = 180;
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
break;
default:
this.deviceOrientation = 270;
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
break;
}
this.setRequestedOrientation(orientation);
LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (LocationListener) this);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, (LocationListener) this);
} catch (Exception ex) {
}
compass = new InternalCompassOrientationProvider(this);
compass.startOrientationProvider(this);
mMapView.getController().zoomTo(14);
}
#Override
public void onLocationChanged(Location location) {
if (mMapView == null)
return;
//after the first fix, schedule the task to change the icon
//mMapView.getController().setCenter(new GeoPoint(location.getLatitude(), location.getLongitude()));
mMapView.invalidate();
gpsbearing = location.getBearing();
gpsspeed = location.getSpeed();
lat = (float) location.getLatitude();
lon = (float) location.getLongitude();
alt = (float) location.getAltitude(); //meters
timeOfFix = location.getTime();
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
#Override
protected void onPause() {
super.onPause();
compass.stopOrientationProvider();
LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
lm.removeUpdates(this);
} catch (Exception ex) {
}
//unlock the orientation
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
Float trueNorth = 0f;
#Override
public void onOrientationChanged(final float orientationToMagneticNorth, IOrientationProvider source) {
GeomagneticField gf = new GeomagneticField(lat, lon, alt, timeOfFix);
trueNorth = orientationToMagneticNorth + gf.getDeclination();
gf=null;
synchronized (trueNorth) {
if (trueNorth > 360.0f) {
trueNorth = trueNorth - 360.0f;
}
//use gps bearing instead of the compass
if (gpsspeed > 0.01f) {
float t = (360 - gpsbearing - this.deviceOrientation);
if (t < 0) {
t += 360;
}
if (t > 360) {
t -= 360;
}
mMapView.setMapOrientation(t);
} else {
//this part adjusts the desired map rotation based on device orientation and compass heading
float t = (360 - trueNorth - this.deviceOrientation);
if (t < 0) {
t += 360;
}
if (t > 360) {
t -= 360;
}
mMapView.setMapOrientation(t);
}
this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (this!=null ) {
Toast.makeText(MainActivity.this, "GPS Speed: " + gpsspeed + "m/s GPS Bearing: " + gpsbearing +
"\nDevice Orientation: " + (int) deviceOrientation + " Compass heading: " + (int) orientationToMagneticNorth + "\n" +
"True north: " + trueNorth.intValue() + " Map Orientation: " + (int) mMapView.getMapOrientation() + "\n", Toast.LENGTH_SHORT).show();
}
}
});
}
}
#Override
public boolean singleTapConfirmedHelper(GeoPoint geoPoint) {
return false;
}
#Override
public boolean longPressHelper(GeoPoint geoPoint) {
return false;
}
}

wrong distance between 2 GPS points - android

I want to get the distance between 2 points, one is getted by GPS and the second is fix. I get a result, but the distance is 40 km but it should be around 25 km and I can't find another formula. Please help me to fix the problem.
btnShowLocation = (Button) getView().findViewById(R.id.btnLocation);
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
//Objekt in der Klasse erzeugen
gps = new GPSTracker(getActivity());
//überprüfen, ob GPS aktiv ist
if(gps.canGetLocation()){
latitude = gps.getLatitude();
longitude = gps.getLongitude();
Toast.makeText(getActivity(), "Deine Location - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}else{
//wenn keine Location gefunden wurde
// GPS oder Netzwerk nicht verfügbar
// User fragen, ob er die Einstellungen ändern will
gps.showSettingsAlert();
}
}
});
btnEntfernung = (Button) getView().findViewById(R.id.btnDistance);
btnEntfernung.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
double x1,y1,x2,y2,radius;
latitudeDB = Math.toRadians(48.569601);
longitudeDB = Math.toRadians(16.572087);
double entfernung=0;
radius= 6378.137/360;
x2=latitudeDB;
y2=longitudeDB;
x1=latitude;
y1=longitude;
double distanz =(x1-x2)+(y1-y2);
double distanzfaktor = Math.acos((Math.sin(y1)*Math.sin(y2))+((Math.cos(y1)*Math.cos(y2))* (Math.cos(x2)-Math.cos(x1))));
if (distanz >=0){
entfernung = radius*distanzfaktor;
}
else if(distanz < 0){
entfernung = radius*(distanzfaktor + Math.PI);
}
Toast.makeText(getActivity(), "Deine Entfernung" + entfernung + " km", Toast.LENGTH_LONG).show();
}
});
Why not use the built-in Location class to do this for you?
x2=latitudeDB;
y2=longitudeDB;
x1=latitude;
y1=longitude;
float[] results = new float[1];
Location.distanceBetween(x1, y1, x2, y2, results);
float distanceInMeters = results[0];
float distanceInKm = distanceInMeters / 1000.0f;
Toast.makeText(getActivity(), "Deine Entfernung" + distanceInKm + " km", Toast.LENGTH_LONG).show();

{Android App} How can I display distance from my current location and specified point?

i have researched this for hours and the only answers i see point me to
http://developer.android.com/reference/android/location/Location.html
and to use the Method
public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
i need help understanding how this works in relation to my app. this is how i am retrieving my location.
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
}
private void updateWithNewLocation(Location location) {
String latLongString;
TextView myLocationText;
myLocationText = (TextView)findViewById(R.id.myLocationText);
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
} else {
latLongString = "No location found";
}
myLocationText.setText("Your Current Position is:\n" +
latLongString);
}
Can someone please help me out a little in understanding how to import my current location into this equation and then having the distance shown in my app?
thank you
public double calcdist()
{
int MILLION = 1000000;
int EARTH_RADIUS_KM = 6371;
double lat1 = la1 / MILLION;// latitude of location 1
double lon1 = lo1 / MILLION; //longitude of location 1
double lat2 = la2 / MILLION; //latitude of location 2
double lon2 = lo2 / MILLION;//longitude of location 2
double lat1Rad = Math.toRadians(lat1);
double lat2Rad = Math.toRadians(lat2);
double deltaLonRad = Math.toRadians(lon2 - lon1);
double dist = Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad)
* Math.cos(deltaLonRad))
* EARTH_RADIUS_KM;
return dist;
}
You can use this code if you already got latitude and longitude of both the locations.
Create a location listener
Method isAccurateForUse is a custom method that simply checks accuracy of a location.
This should work:
public boolean locChanged = false;
public LocationManager locMgr = null;
public Location referenceL = null; // Your reference location
public Location currentKL = null; // Current known location
public Location currentLKL = null; // Current last known location
//Initialise the GPS listener
locMgr = (LocationManager) appCtx.getSystemService(Context.LOCATION_SERVICE);
locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, fixGpsListener);
currentLKL = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//Define the GPS listener
LocationListener fixGpsListener = new LocationListener()
{
public void onLocationChanged(Location location)
{
locChanged = true;
if (currentKL == null)
currentKL = location;
else if (isAccurateForUse())
{
currentLKL = currentKL;
currentKL = location;
updateDistance(meterToKilometer(currentKL.distanceTo(referenceL)));
}
}
public void onProviderDisabled(String provider)
{}
public void onProviderEnabled(String provider)
{}
public void onStatusChanged(String provider, int status, Bundle extras)
{}
};
currentKL.distanceTo(referenceL) >> gives the distance in meters
meterToKilometer >> converts meters to kilo-meters
updateDistance >> this method takes a string and updates a text-view that shows distance.
Cheers

Categories

Resources