38

Android デバイスの移動量を検出する方法について提案が必要です。電話をテーブルまたはベッドに置き、誰かがテーブルをタップしたり、ベッドに座ったり横になったりした場合、Android デバイスの動きを検出したいとします。

実際、AndroidにはモーションセンサーAPIがあることは知っていますが、使用するセンサーと、このタイプの動き検出に最適なセンサータイプはわかりません。

誰かが基本的なデモ コードを共有できれば幸いです。

4

6 に答える 6

63

間違いなく加速度計で動作します:

// Start with some variables
private SensorManager sensorMan;
private Sensor accelerometer;

private float[] mGravity;
private float mAccel;
private float mAccelCurrent;
private float mAccelLast;

// In onCreate method
sensorMan = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccel = 0.00f;
mAccelCurrent = SensorManager.GRAVITY_EARTH;
mAccelLast = SensorManager.GRAVITY_EARTH;

// And these:

@Override
public void onResume() {
    super.onResume();
    sensorMan.registerListener(this, accelerometer,
        SensorManager.SENSOR_DELAY_UI);
}

@Override
protected void onPause() {
    super.onPause();
    sensorMan.unregisterListener(this);
}

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
        mGravity = event.values.clone();
        // Shake detection
        float x = mGravity[0];
        float y = mGravity[1];
        float z = mGravity[2];
        mAccelLast = mAccelCurrent;
        mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z);
        float delta = mAccelCurrent - mAccelLast;
        mAccel = mAccel * 0.9f + delta;
            // Make this higher or lower according to how much
            // motion you want to detect
        if(mAccel > 3){ 
        // do something
        }
    }

}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // required method
}
于 2013-01-29T03:05:49.623 に答える
18

次のクラスを使用しました。

public class MovementDetector implements SensorEventListener {

protected final String TAG = getClass().getSimpleName();

private SensorManager sensorMan;
private Sensor accelerometer;

private MovementDetector() {
}

private static MovementDetector mInstance;

public static MovementDetector getInstance() {
    if (mInstance == null) {
        mInstance = new MovementDetector();
        mInstance.init();
    }
    return mInstance;
}

//////////////////////
private HashSet<Listener> mListeners = new HashSet<MovementDetector.Listener>();

private void init() {
    sensorMan = (SensorManager) GlobalData.getInstance().getContext().getSystemService(Context.SENSOR_SERVICE);
    accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
}

public void start() {
    sensorMan.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}

public void stop() {
    sensorMan.unregisterListener(this);
}

public void addListener(Listener listener) {
    mListeners.add(listener);
}

/* (non-Javadoc)
 * @see android.hardware.SensorEventListener#onSensorChanged(android.hardware.SensorEvent)
 */
@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {

        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        float diff = (float) Math.sqrt(x * x + y * y + z * z);
        if (diff > 0.5) // 0.5 is a threshold, you can test it and change it
            Log.d(TAG,"Device motion detected!!!!");
        for (Listener listener : mListeners) {
            listener.onMotionDetected(event, diff);
        }
    }

}

/* (non-Javadoc)
 * @see android.hardware.SensorEventListener#onAccuracyChanged(android.hardware.Sensor, int)
 */
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub

}

public interface Listener {
    void onMotionDetected(SensorEvent event, float acceleration);
    }
}

使用法:

私の活動についてonCrate()

        MovementDetector.getInstance().addListener(new MovementDetector.Listener() {

        @Override
        public void onMotionDetected(SensorEvent event, float acceleration) {

            mMotionDetectionTextView.setText("Acceleration: ["+String.format("%.3f",event.values[0])+","+String.format("%.3f",event.values[1])+","+String.format("%.3f",event.values[2])+"] "+String.format("%.3f", acceleration));
            if (acceleration > SettingsHelper.getInstance().getMotionDetectionThreshold()){
                mMotionDetectionTextView.setTextColor(Color.RED);
            } else {
                mMotionDetectionTextView.setTextColor(Color.WHITE);
            }

        }
    });

私の活動についてonResume()

MovementDetector.getInstance().start();

私の活動についてonPause()

MovementDetector.getInstance().stop();
于 2015-06-22T17:47:58.027 に答える
5

このコードは歩行検出用です (@anthropomo コードを改変)

よりスムーズな値を取得します。

// 初期化

private SensorManager sensorMan;
private Sensor accelerometer;

private float[] mGravity;
private double mAccel;
private double mAccelCurrent;
private double mAccelLast;

private boolean sensorRegistered = false;

// onCreate

    sensorMan = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
    accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    mAccel = 0.00f;
    mAccelCurrent = SensorManager.GRAVITY_EARTH;
    mAccelLast = SensorManager.GRAVITY_EARTH;

    sensorMan.registerListener(this, accelerometer,
            SensorManager.SENSOR_DELAY_NORMAL);
    sensorRegistered = true;

// onSensorChanged

private int hitCount = 0;
private double hitSum = 0;
private double hitResult = 0;

private final int SAMPLE_SIZE = 50; // change this sample size as you want, higher is more precise but slow measure.
private final double THRESHOLD = 0.2; // change this threshold as you want, higher is more spike movement

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        mGravity = event.values.clone();
        // Shake detection
        double x = mGravity[0];
        double y = mGravity[1];
        double z = mGravity[2];
        mAccelLast = mAccelCurrent;
        mAccelCurrent = Math.sqrt(x * x + y * y + z * z);
        double delta = mAccelCurrent - mAccelLast;
        mAccel = mAccel * 0.9f + delta;

        if (hitCount <= SAMPLE_SIZE) {
            hitCount++;
            hitSum += Math.abs(mAccel);
        } else {
            hitResult = hitSum / SAMPLE_SIZE;

            Log.d(TAG, String.valueOf(hitResult));

            if (hitResult > THRESHOLD) {
                Log.d(TAG, "Walking");
            } else {
                Log.d(TAG, "Stop Walking");
            }

            hitCount = 0;
            hitSum = 0;
            hitResult = 0;
        }
    }
}
于 2016-07-27T04:53:36.743 に答える
0

デモ コードはありませんが (十分に具体的でないため)、良いスタートはここにあります: http://developer.android.com/guide/topics/sensors/sensors_motion.html (および左側のその他の項目) )。

于 2013-01-29T02:56:04.450 に答える