我正在使用距离/时间来计算速度,但是当位置改变时,它会上升到无穷大并逐渐减小。
package water.Spill;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.util.FloatMath;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import water.Spill.LatLon;
import android.hardware.Camera;
public class GPS2 extends Activity implements SurfaceHolder.Callback {
LocationManager locationManager;
LocationListener locationListener;
//text views to display latitude and longitude
TextView latituteField;
TextView longitudeField;
TextView currentSpeedField;
TextView kmphSpeedField;
TextView avgSpeedField;
TextView avgKmphField;
TextView gpsOnOff;
//objects to store positional information
protected double lat;
protected double lon;
ArrayList<LatLon> myList = new ArrayList<LatLon>();
//objects to store values for current and average speed
protected double currentSpeed;
protected double kmphSpeed;
protected double avgSpeed;
protected double avgKmph;
protected double totalSpeed;
protected double totalKmph;
//Camera
private SurfaceView mSurfaceView ;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private boolean mPreviewRunning;
boolean gps_enabled = false;
boolean network_enabled = false;
//counter that is incremented every time a new position is received, used to calculate average speed
int counter = 0;
double totalDistance=0;
//timer
TextView text3;
TextView secondLabel;
TextView minutesLabel;
TextView hourLabel;
long starttime = 0;
long spdstarttime = 0;
Handler h2 = new Handler();
Runnable run = new Runnable() {
public void run() {
long spdmillis = System.currentTimeMillis() - spdstarttime;
long millis = System.currentTimeMillis() - starttime;
int spdseconds = (int) (spdmillis / 1000);
int spdhours = spdseconds/60/60;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
int hours = minutes/60;
seconds = seconds % 60;
minutes = minutes % 60;
currentSpeedField = (TextView) findViewById(R.id.speed);
secondLabel = (TextView) findViewById(R.id.seconds);
minutesLabel = (TextView) findViewById(R.id.minutes);
hourLabel = (TextView) findViewById(R.id.hour);
secondLabel.setText(String.valueOf(seconds) + "s");
minutesLabel.setText(String.valueOf(minutes)+ "m");
hourLabel.setText(String.valueOf(hours)+ "h");
if(myList.size() > 1){
LatLon ll1 = myList.get(myList.size()-2);
LatLon ll2 = myList.get(myList.size()-1);
double distance = 0;
distance = distFrom(ll1.getLat(), ll1.getLon(), ll2.getLat(), ll2.getLon());
if(ll1.getLat()== ll2.getLat() && ll1.getLon() == ll2.getLon()){
currentSpeed = 0;
}
else{
distance = round(distance,3,BigDecimal.ROUND_HALF_UP);
currentSpeed = (distance*1000)/spdseconds;
double test12 = spdseconds;
System.out.println("distance " + (distance*1000));
System.out.println("time " + test12);
//currentSpeed = round(currentSpeed,3,BigDecimal.ROUND_HALF_UP);
}
currentSpeedField.setText(String.valueOf(currentSpeed) + "km/h");
}
h2.postDelayed(this, 500);
}
};
Timer timer = new Timer();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gps2);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
text3 = (TextView)findViewById(R.id.text3);
Button b = (Button)findViewById(R.id.button);
b.setText("stop");
timer = new Timer();
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Button b = (Button)v;
b.setText("stop");
if(b.getText().equals("stop")){
timer.cancel();
timer.purge();
h2.removeCallbacks(run);
stop();
Button bStop = (Button)findViewById(R.id.button4);
bStop.setEnabled(true);
b.setEnabled(false);
}
}
});
run();
Button b2 = (Button)findViewById(R.id.button4);
b2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getLocation();
h2.postDelayed(run, 0);
starttime = System.currentTimeMillis();
Button bStart = (Button)findViewById(R.id.button4);
bStart.setEnabled(false);
Button b = (Button)findViewById(R.id.button);
b.setEnabled(true);
}
});
}
private void getLocation() {
{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0,locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,0,locationListener);
}
}
public void stop(){
locationManager.removeUpdates(locationListener);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
locationManager.removeUpdates(locationListener);
super.onPause();
}
private void run(){
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setSpeedRequired(true);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
//Acquire a reference to the system Location Manager
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
try{network_enabled=locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
try{gps_enabled=locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
// Define a listener that responds to location updates
locationListener = new MyLocationListener();
String Results="Unavailable";
Button bStart = (Button)findViewById(R.id.button4);
bStart.setEnabled(false);
TextView gpsOnOff = (TextView) findViewById(R.id.gpsOnOff);
if(network_enabled)
{
Results="Available";
Button bStartGot = (Button)findViewById(R.id.button4);
bStartGot.setEnabled(true);
}
else if(gps_enabled)
{
Results="Available";
Button bStartGot = (Button)findViewById(R.id.button4);
bStartGot.setEnabled(true);
gpsOnOff.setText(Results);
}
}
//Method to round the doubles to a max of 3 decimal places
public static double round(double unrounded, int precision, int roundingMode)
{
BigDecimal bd = new BigDecimal(unrounded);
BigDecimal rounded = bd.setScale(precision, roundingMode);
return rounded.doubleValue();
}
public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 6371;
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2 -lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
return dist;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location newLocation)
{
//current speed fo the gps device
spdstarttime = System.currentTimeMillis();
//kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);
//all speeds added together
totalSpeed = totalSpeed + currentSpeed;
totalKmph = totalKmph + kmphSpeed;
//calculates average speedss
//avgSpeed = round(totalSpeed/counter,3,BigDecimal.ROUND_HALF_UP);
//avgKmph = round(totalKmph/counter,3,BigDecimal.ROUND_HALF_UP);
//gets position
lat = round(((double) (newLocation.getLatitude())),9,BigDecimal.ROUND_HALF_UP);
lon = round(((double) (newLocation.getLongitude())),9,BigDecimal.ROUND_HALF_UP);
latituteField = (TextView) findViewById(R.id.lat);
longitudeField = (TextView) findViewById(R.id.lon);
TextView distanceField = (TextView) findViewById(R.id.distance);
LatLon ll = new LatLon(lat, lon);
myList.add(ll);
if(myList.size() > 1){
LatLon ll2 = myList.get(myList.size()-2);
double dist = distFrom( ll2.getLat(), ll2.getLon(), ll.getLat(), ll.getLon());
dist = round(dist,3,BigDecimal.ROUND_HALF_UP);
totalDistance += dist;
totalDistance = round(totalDistance,3,BigDecimal.ROUND_HALF_UP);
distanceField.setText("Distance: " + String.valueOf(totalDistance)+ "km");
Context context = getApplicationContext();
CharSequence text = "Location Changed , Distance Accumulated";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lon));
}
public void onProviderDisabled(String provider)
{
}
public void onProviderEnabled(String provider)
{
}
public void onStatusChanged(String provider, int status, Bundle extras) {
if(status==LocationProvider.OUT_OF_SERVICE)
{
gpsOnOff.setText("OFF");
}
else
{
if(status==LocationProvider.TEMPORARILY_UNAVAILABLE)
{
gpsOnOff.setText("OFF");
}
else
{
if(status==LocationProvider.AVAILABLE)
{
gpsOnOff.setText("ON");
}
}
}
}
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
/*if (imageData != null) {
Intent mIntent = new Intent();
StoreByteImage(mContext, imageData, 50,
"ImageName");
mCamera.startPreview();
setResult(FOTO_MODE, mIntent);
finish();
}*/
}
};
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// TODO Auto-generated method stub
if (mPreviewRunning) {
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
List<Camera.Size> list = p.getSupportedPreviewSizes ();
Camera.Size size = list.get(0);
p.setPreviewSize(size.width, size.height);
mCamera.setParameters(p);
//p.setPreviewSize(w, h);
//p.setPreviewSize(300, 200);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
mCamera = Camera.open();
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
}
}
答案 0 :(得分:1)
有时两个地点之间的时间不到一秒。因此dist / time =>
无穷大。 (您是否使用浮点变量进行速度计算?)
无论如何,你不需要这样做来计算速度。
使用:
Location.getSpeed();
问题解决了。
注意:您必须移动才能看到非零速度。此值的准确性还取决于手机中使用的GPS芯片组。有些设备使用其他传感器来计算此速度。