问题
i have created an speedometer application which uses accelerometer to calculate device speed. here is the code: `package com.exacmple.speedo;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class Speedometer extends Activity {
SensorManager sensorManager;
TextView myTextView;
float appliedAcceleration = 0;
float currentAcceleration = 0;
float velocity = 0;
Date lastUpdate;
Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myTextView = (TextView) findViewById(R.id.myTextView);
lastUpdate = new Date(System.currentTimeMillis());
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(sensorListener,
SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_FASTEST);
Timer updateTimer = new Timer("velocityUpdate");
updateTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateGUI();
}
}, 0, 1000);
}
private void updateGUI() {
// Convert from m/s to mph
final double mph = (Math.round(100 * velocity / 1.6 * 3.6)) / 100;
// Update the GUI
handler.post(new Runnable() {
public void run() {
myTextView.setText(String.valueOf(mph) + "mph");
}
});
}
private void updateVelocity() {
// Calculate how long this acceleration has been applied.
Date timeNow = new Date(System.currentTimeMillis());
long timeDelta = timeNow.getTime() - lastUpdate.getTime();
lastUpdate.setTime(timeNow.getTime());
// Calculate the change in velocity at the
// current acceleration since the last update.
float deltaVelocity = appliedAcceleration * (timeDelta / 1000);
appliedAcceleration = currentAcceleration;
// Add the velocity change to the current velocity.
velocity += deltaVelocity;
// Convert from meters per second to miles per hour.
double mph = (Math.round(velocity / 1.6 * 3.6));
myTextView.setText(String.valueOf(mph) + "mph");
}
private final SensorListener sensorListener = new SensorListener() {
double calibration;
public void onSensorChanged(int sensor, float[] values) {
double x = values[SensorManager.DATA_X];
double y = values[SensorManager.DATA_Y];
double z = values[SensorManager.DATA_Z];
double a = -1
* Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)
+ Math.pow(z, 2));
if (calibration == Double.NaN)
calibration = a;
else {
updateVelocity();
currentAcceleration = (float) a;
}
}
public void onAccuracyChanged(int sensor, int accuracy) {
}
};
}` the problem i am facing is that it doesn't show any change in initial speed that is 0.0 mph in my case. i had checked it on logcat, it shows speed their but does not show any increments on UI. please help.
回答1:
I think your method of using a handler for the updateGUI is what is causing your problem; along with timing within your program loop. I tried to build a prototype of what you're saying from your code, and it seems it only wants to update once. Then I made a few mods, one of which was removing the handler. Get this, when I did this it will update the textView ONLY when clicked and held for a second on the emulator title banner (dual monitor display setup on Win7). Never seen anything like it, but I'm assuming it's launching the function due to some sort of state change in the emulation software though. Sorry I couldn't be of more help, but just letting you know you're on the right path. If I solve this program I'll be sure to post results.
回答2:
Just call updateGUI
at the end of onSensorChanged
. There is no point in updating the UI if the velocity hasn't changed, so it's also more efficient.
回答3:
Isn't that code going to just constantly accumulate at ~9.8m/ss ? Maybe you want to only integrate the component tangent to the earth surface.
来源:https://stackoverflow.com/questions/5321476/speedometer-using-accelerometer-no-output