Android:加速计传感器中的z值范围在不同设备上有所不同

时间:2012-10-22 19:11:29

标签: android accelerometer sensor

我想检测设备是否朝上。 (没有倾斜但是朝向地面平坦) 在某些面向上的设备上,z值将返回9到10之间的值。 (大多数设备)
但是,在Nexus 7上,面向上,z值将返回6~8之间的值。

我的代码是:

if(z_value > 9.0) {
    // device facing up
}
else {
    // device is in angled
}

但是,上面的代码不再起作用了。由于Nexus7未达到z_value为9。

如何检测设备是否面向(完全)。 (不要求z_value> 0)

我的完整代码如下:

@Override
protected void onStart() {
    super.onStart();
    try {
        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
        if(sensorList.size() > 0){
            accelerometerPresent = true;
            accelerometerSensor = sensorList.get(0);  
        }
        else{
            accelerometerPresent = false;  
        }
        if(accelerometerPresent){
            sensorManager.registerListener(accelerometerListener, accelerometerSensor, SensorManager.SENSOR_DELAY_UI);
        }
    } catch(Exception e) {}
}

private SensorEventListener accelerometerListener = new SensorEventListener(){

            @Override
            public void onAccuracyChanged(Sensor arg0, int arg1) {}

            @Override
            public void onSensorChanged(SensorEvent arg0) {
                float z_value = arg0.values[2];
                Log.d("test", "z:" + z_value);
            }};

注意#1
对于Nexus 7,arg0.sensor.getMaximumRange()返回19.6133。哪个传感器永远不会返回。

注意#2
如果你摇动设备,z_value往往会更高(有时8到8.5)。 如果您稳定地倾斜设备,则z_value不会达到8(最大值)。

2 个答案:

答案 0 :(得分:2)

显然,设备校准不佳。经过良好校准的设备应该返回9.81m / s ^ 2,即重力加速度。

您可以做什么:将z值与x和y值进行比较。如果z值占主导地位,则设备面朝上。例如:

if (z/sqrt(x^2+y^2+z^2+1.0e-6) > 0.9) { // Facing up

我添加了术语1.0e-6,这样您就不会意外地除以零。

这种启发式方法需要测试和调整,但我想你明白了。祝你好运!

答案 1 :(得分:-1)

关于这种传感器的一般想法是避免它们,或者不要滥用它们,使得应用程序依赖于非常精确的测量。

这种传感器的问题基本上是它们具有非常不同的值范围并且它们非常嘈杂,因此它们需要由您,编码器进行标准化,并且它们在准确性方面不能如此可靠。 / p>

我忘记了这个公开演讲的确切名称,但即便是谷歌和Android团队也建议不要依赖于小数或者不要求高精度;还要记住,这款智能手机和平板电脑的每一小部分都非常便宜,我们所说的传感器通常价格不超过1美元。

尝试以一种代码只需要一般方向或轴的方式进行编码,如果你想要一个值,请确保它是一个整数,并且总是进行粗略计算并且不要求精度或小数。

另请注意,Android不提供此值的规范化方法,因此您必须在代码中处理。