Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
306 views
in Technique[技术] by (71.8m points)

android - How can I get the direction of movement using an accelerometer?

I'm developing a Android application and I would like to know if is possible detect the direction of movement with one axis fixed. For example, I want put my phone on the table and detect the direction when I move it (left, right, up and down). The distance is not necessary, I just want know the accurate direction.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes.

Using the SensorEventListener.onSensorChanged(SensorEvent event) you can determine the values provided along the X & Y axis. You would need to record these values and then compare them to any new values that you receive on subsequent calls to the onSensorChanged method to get a delta value. If the delta value on one axis is positive then the device is moving one way, if its negative its moving the opposite way.

You will probably need to fine tune both the rate at which you receive accelerometer events and the threshold at which you consider a delta value to indicate a change in direction.

Here's a quick code example of what I'm talking about:

public class AccelerometerExample extends Activity implements SensorEventListener {
    TextView textView;
    StringBuilder builder = new StringBuilder();

    float [] history = new float[2];
    String [] direction = {"NONE","NONE"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView = new TextView(this);
        setContentView(textView);

        SensorManager manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Sensor accelerometer = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
        manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        float xChange = history[0] - event.values[0];
        float yChange = history[1] - event.values[1];

        history[0] = event.values[0];
        history[1] = event.values[1];

        if (xChange > 2){
          direction[0] = "LEFT";
        }
        else if (xChange < -2){
          direction[0] = "RIGHT";
        }

        if (yChange > 2){
          direction[1] = "DOWN";
        }
        else if (yChange < -2){
          direction[1] = "UP";
        }

        builder.setLength(0);
        builder.append("x: ");
        builder.append(direction[0]);
        builder.append(" y: ");
        builder.append(direction[1]);

        textView.setText(builder.toString());
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // nothing to do here
    }
}

This code will only provide you with the general direction on the X and Y axis that the phone has moved in. To provide a more fine grained determination of direction (e.g. to attempt to mimic the movement of a computer mouse) you might find that a phone's accelerometer is not fit for purpose.

To attempt this, I would first set the sensor delay to SensorManager.SENSOR_DELAY_FAST and create a list of multiple history events so that I could detect movement over time and not be influenced by slight movements in the opposite direction that often happen when taking accelerometer measurements at such a fine level. You would also need to measure the amount of time that has passed to help calculate the accurate measure of movement as suggested in your comments.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...