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

Posted

技术标签:

【中文标题】这个加速度计传感器监听器背后使用了啥逻辑【英文标题】:What logic is used behind this accelerometer sensor listener这个加速度计传感器监听器背后使用了什么逻辑 【发布时间】:2011-08-08 19:44:49 【问题描述】:

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

    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】:

将此添加到您的活动类中

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

我希望这会有所帮助

【讨论】:

以上是关于这个加速度计传感器监听器背后使用了啥逻辑的主要内容,如果未能解决你的问题,请参考以下文章

Android 加速度计传感器值

减慢 android 加速度计更新

重力传感器监听器不工作

尽管文档说了啥,但复合 Android 传感器不存在

关于安卓手机三轴加速度传感器的一些问题。

如何使用设备的加速度计检测运动增加然后突然停止?