这个加速度计传感器监听器背后使用了什么逻辑

时间:2011-08-08 19:44:50

标签: android accelerometer sensor shake android-sensors

这是我用来捕捉手机震动的代码:

    public void onSensorChanged(SensorEvent event) {
        Sensor mySensor = event.sensor;
        if (mySensor.getType() == SensorManager.SENSOR_ACCELEROMETER) {
            long curTime = System.currentTimeMillis();
            // only allow one update every 100ms.
            if ((curTime - lastUpdate) > 100) {
                long diffTime = (curTime - lastUpdate);
                lastUpdate = curTime;

                x = event.values[SensorManager.DATA_X];
                y = event.values[SensorManager.DATA_Y];
                z = event.values[SensorManager.DATA_Z];

                float speed = Math.abs(x+y+z - last_x - last_y - last_z)/ diffTime * 10000;
                if (speed > SHAKE_THRESHOLD_HIGH) {
                    // yes, this is a shake action! Do something about it!
                    handshake_score.setText(String.valueOf(speed));
                    new AlertDialog.Builder(Handshake.this)
                    .setCancelable(true)
                    .setIcon(android.R.drawable.ic_dialog_info)
                    .setTitle("noo")
                    .setMessage("too much") 
                    .setPositiveButton("OK!", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                                dialog.cancel();
                            }
                        })
                    .show();

                    last_x = x;
                    last_y = y;
                    last_z = z;

                } else if (speed > SHAKE_THRESHOLD_PASS) {
                    // yes, this is a shake action! Do something about it!
                    handshake_score.setText(String.valueOf(speed));
                    sensorMgr.unregisterListener(this);
                    new AlertDialog.Builder(Handshake.this)
                    .setCancelable(true)
                    .setIcon(android.R.drawable.ic_dialog_info)
                    .setTitle("HAHAA!")
                    .setMessage("good") 
                    .setPositiveButton("OK!", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                                dialog.cancel();
                            }
                        })
                    .show();

                    finish();

                } else if (speed > SHAKE_THRESHOLD_SMALL) {
                    // yes, this is a shake action! Do something about it!
                    handshake_score.setText(String.valueOf(speed));
                    new AlertDialog.Builder(Handshake.this)
                    .setCancelable(true)
                    .setIcon(android.R.drawable.ic_dialog_info)
                    .setTitle("boo")
                    .setMessage("not enough") 
                    .setPositiveButton("OK!", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                                dialog.cancel();
                            }
                        })
                    .show();

                    last_x = x;
                    last_y = y;
                    last_z = z;
                }
                last_x = x;
                last_y = y;
                last_z = z;
            }
        }           
  }

我想做的就是模仿握手,这样当水平握住手机时,它会响应手机上下移动,就好像你正对着横向屏幕并上下移动一样。

虽然这段代码反映了扭动手机,就好像你绕着长轴旋转手机一样。

有人可以解释这段代码中使用的坐标x,y和z背后的逻辑,这些是电话中的位置,以及我如何让phoen响应“握手”,而不是在手中扭转它。

有关此类代码的任何想法吗?

1 个答案:

答案 0 :(得分:0)

在您的活动类

中添加此内容
/* put this into your activity class */
private SensorManager mSensorManager;
private float mAccel; // acceleration apart from gravity
private float mAccelCurrent; // current acceleration including gravity
private float mAccelLast; // last acceleration including gravity

private final SensorEventListener mSensorListener = new SensorEventListener() {

 public void onSensorChanged(SensorEvent se) {
  float x = se.values[0];
  float y = se.values[1];
  float z = se.values[2];
  mAccelLast = mAccelCurrent;
  mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
  float delta = mAccelCurrent - mAccelLast;
  mAccel = mAccel * 0.9f + delta; // perform low-cut filter
}

public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
 };

 @Override
 protected void onResume() {
  super.onResume();
 mSensorManager.registerListener(mSensorListener,   mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),   SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onStop() {
mSensorManager.unregisterListener(mSensorListener);
super.onStop();
}

并将其添加到onCreate方法中:

 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener,    mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
mAccel = 0.00f;
mAccelCurrent = SensorManager.GRAVITY_EARTH;
mAccelLast = SensorManager.GRAVITY_EARTH;

我希望这会有所帮助