如何使用 GPS 高精度计算每 15 秒的距离
How to calculate distance every 15 sec with using GPS heavy accuracy
我通过 Map.getMyLocation().getLatitude()
、locationManager
和 mGoogleApiClient
等 3 种方式获取 GPS 位置。
但是这些对我每 15 秒计算一次距离没有帮助。
问题是位置纬度和经度不准确,即我使用这些距离计算方式步行 1-2 米。计算距离为 400 m-600 米,有时也显示 1 公里。 GPS 位置在 20 米到 600 米之间变化。 请提供一些更好的想法,以了解如何通过在 android 中每 15 秒计算一次距离来使我的位置非常准确.
这是我的代码
//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);
这是我的距离计算方法
但是这个方法不是问题
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;
}
您可以使用 requestLocation update 开始获取位置更新:
mylistener = new MyLocationListener();
locationManager.requestLocationUpdates(provider, 150000, 1, mylistener);
这里你会在每 15 秒和 1 米位置变化后得到更新:
当 locationmanager 获取位置更新时,它会调用 onLocationChanged() 方法。您将在那里获得更新的位置。
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
}
//Do your code with this updated location
}
您可以设置条件位置收集。如果你想获得准确的位置,我建议你只使用 GPS_PROVIDER。请记住,虽然 GPS 在屋内无法正常工作。
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);
全局声明 -
float distanceInMeters = 0;
在 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;
}
注意: 我已将第一个位置值更改为 previousLocation 以避免混淆。
正如评论部分中有人发布的那样,使用 LocationManager /FusedLocationApi。您可以额外做的是:
- 即使您每 15 秒需要一次位置,也可以以较小的间隔或连续获取一次,然后进行计算。这会给设备的电池带来压力。
- 如果您获得的新位置与上一个位置相距很远,请忽略它。有些设备可能 return 错误的值(有一个 Nexus5 现在可以工作,下一秒就会显示 4-5 公里以外的地方)。
- 如果电池有问题,请将间隔设置为 15 秒,也许 PRIORITY_BALANCED_POWER_ACCURACY,但请确保您有后备。如果两个位置之间的距离太大或读数的准确性不好,请忽略 it/request 另一个位置。
请检查这个
点赞
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>
清单中的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
输出
在一个答案中,代码:
distanceInMeters += previousLocation.distanceTo(location);
很好,但我建议 - 除非有人发现它有问题,否则只需使用:
locationManager.requestLocationUpdates(provider, 0, DISTANCE, mylistener);
并累积DISTANCE(前提是它是一个相对较小的DISTANCE)。对不起,我不能把它放在评论中,因为他们删除了很多积分。
编辑:但 distanceInMeters += previousLocation.distanceTo(location) 比我上面建议的更准确。
我通过 Map.getMyLocation().getLatitude()
、locationManager
和 mGoogleApiClient
等 3 种方式获取 GPS 位置。
但是这些对我每 15 秒计算一次距离没有帮助。
问题是位置纬度和经度不准确,即我使用这些距离计算方式步行 1-2 米。计算距离为 400 m-600 米,有时也显示 1 公里。 GPS 位置在 20 米到 600 米之间变化。 请提供一些更好的想法,以了解如何通过在 android 中每 15 秒计算一次距离来使我的位置非常准确.
这是我的代码
//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);
这是我的距离计算方法 但是这个方法不是问题
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;
}
您可以使用 requestLocation update 开始获取位置更新:
mylistener = new MyLocationListener();
locationManager.requestLocationUpdates(provider, 150000, 1, mylistener);
这里你会在每 15 秒和 1 米位置变化后得到更新:
当 locationmanager 获取位置更新时,它会调用 onLocationChanged() 方法。您将在那里获得更新的位置。
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
}
//Do your code with this updated location
}
您可以设置条件位置收集。如果你想获得准确的位置,我建议你只使用 GPS_PROVIDER。请记住,虽然 GPS 在屋内无法正常工作。
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);
全局声明 -
float distanceInMeters = 0;
在 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;
}
注意: 我已将第一个位置值更改为 previousLocation 以避免混淆。
正如评论部分中有人发布的那样,使用 LocationManager /FusedLocationApi。您可以额外做的是:
- 即使您每 15 秒需要一次位置,也可以以较小的间隔或连续获取一次,然后进行计算。这会给设备的电池带来压力。
- 如果您获得的新位置与上一个位置相距很远,请忽略它。有些设备可能 return 错误的值(有一个 Nexus5 现在可以工作,下一秒就会显示 4-5 公里以外的地方)。
- 如果电池有问题,请将间隔设置为 15 秒,也许 PRIORITY_BALANCED_POWER_ACCURACY,但请确保您有后备。如果两个位置之间的距离太大或读数的准确性不好,请忽略 it/request 另一个位置。
请检查这个 点赞
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>
清单中的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
输出
在一个答案中,代码:
distanceInMeters += previousLocation.distanceTo(location);
很好,但我建议 - 除非有人发现它有问题,否则只需使用:
locationManager.requestLocationUpdates(provider, 0, DISTANCE, mylistener);
并累积DISTANCE(前提是它是一个相对较小的DISTANCE)。对不起,我不能把它放在评论中,因为他们删除了很多积分。
编辑:但 distanceInMeters += previousLocation.distanceTo(location) 比我上面建议的更准确。