Какая логика используется за этим слушателем датчика акселерометра - PullRequest
0 голосов
/ 08 августа 2011

Это код, который я использую для захвата дрожания телефона:

    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, используемых в этом коде, где они находятся с точки зрения места в телефоне и как я могу заставить фена реагировать на «рукопожатия», а не крутить его в руке.

есть идеи для такого кода?

1 Ответ

0 голосов
/ 12 января 2012

добавьте это в свой класс деятельности

/* 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;

Надеюсь, это поможет

...