先铺出一列参考文,我觉得都不错的,虽然我要的功能很简单的说。最后补充上自己备忘的一小点内容《android 方向传感器》 http://hi.baidu.com/dean_wang/blog/item/7662a8f8e5efe3c4b58f312b.html
《深入探讨 Android 传感器》 http://www.ibm.com/developerworks/cn/opensource/os-android-sensor/
《官方文档》 http://developer.android.com/reference/android/hardware/SensorManager.html
《Android Orientation Sensor tutorial》 http://blog.androgames.net/135/android-orientation-tutorial/
《Android方向传感器实践——自己动手做水平尺》 http://blog.csdn.net/tinya0913/article/details/6095307
ok,图文我都借用了一下.,
x 方向就是手机的水平方向,右为正
y 方向就是手机的水平垂直方向,前为正
z 方向就是手机的空间垂直方向,天空的方向为正,地球的方向为负
方向角的定义是手机y轴 水平面上的投影 与 正北方向的夹角。 (值得范围是 0 ~ 359 其中0=North, 90=East, 180=South, 270=West)
倾斜角的定义是手机y轴 与水平面的夹角 (手机z轴向y轴方向移动为正 ,值得范围是 -180 ~ 180)
旋转角的定义是手机x轴 与水平面的夹角 (手机x轴离开z轴方向为正, 值得范围是 -90 ~ 90)
也就是说,当你把手机水平放置在桌面上(屏幕向上)且手机指向正北(Y轴方向),此时传感器获得的xyz三个值应该都为0。
以上是我在较早一段时间前已经掌握到的知识。
现在我的疑问是,我手头有个项目需要用户以DC的姿势握持设备(横握x轴向上,z轴屏幕面向用户),这个时候,传感器对xyz三轴的定义会否变化呢?
代码如下:
1. 首先修改 Manifest.xml,使应用以横屏显示
<activity android:name="
SensorTest
" android:label="@string/app_name"
android:screenOrientation="landscape">
2. 再看源码,加入方向传感器的部分
public class SensorTest extends Activity implements SensorEventListener {
//定义SensorManager
private SensorManager mSM;
private boolean mRegisteredSensor;
... ...
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//方向传感器,获取lisener在 onResume()
mSM = (SensorManager) getSystemService(SENSOR_SERVICE);
... ...
}
@Override
public void onResume(){
super.onResume();
List<Sensor> sensors = mSM.getSensorList(Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0){
Sensor sensor = sensors.get(0);
mRegisteredSensor = mSM.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
} else{} //如果这台设备不具备方向传感器..这里就获取不到sensors
}
@Override
public void onPause(){
if (mRegisteredSensor){ //注销Listener
mSM.unregisterListener(this);
mRegisteredSensor = false;
}
super.onPause();
}
@Override
public void
onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
//方向传感器改变方向时
@Override
public void
onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
//获得三轴的数值
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
//输出调试信息至app的标题栏
setTitle(“x,y,z:("+x+","+y+","+z+")”);
}
}
//-----------以上代码省略了不少无关的东西----------------为Class SensorTest 添加 implements SensorEventListener 后,eclipse 提示自动补充了两个方法
public void onAccuracyChanged() 这是当传感器的精度改变时触发的,我暂时还用不上
和 public void onSensorChanged() 这个是我需要的,获得三轴角度的数据,具体用法见上例
这个时候还不能得到数据,还需要为 SensorManager 设置一个Listener, 具体见 onResume() ;
相应地,我还在onPause() 对这个Listener 注销。
ok,那么就可以试运行了,横握手机水平稳定地改变方向,发现变更数值的是x轴值。
很郁闷的是读数和上文的x轴定义不一样,当我机背摄像头正对东面的时候x显示0??.. 0不是应该是正北么?
试了不同的方向,发现角度都有恒定的90的偏差值....(这不是误差吧?大吃一斤)
修改了一下Manifest,改成竖屏,这下x的值变得更怪了..很飘~而且读不懂和横屏之间的数值差异
... ... 苦思片刻...茅塞顿开,我擦!我已开始对上面第一段xyz轴的读数理解错了!x的确是方向,作为罗盘时正确放置或握持方式是像上文所说的水平屏幕朝上,手机顶部指示(沿y轴方向)的x夹角;而我这个项目要求是以机背摄像头的指示方向作为参考基准(也就是沿z轴的负方向),那么得到的x值依然是代表方向,只是存在那个一开始搞不懂的-90度误差
简单地说就是水平伸出左手手掌,掌心向上拇指伸直;这个时候如果中指代表的是摄像头的方向,那么原y轴也就是x值的参考坐标是拇指指向的方向。那自然是存在-90度的偏差。哈哈哈,
结论就是xyz三轴的值和应用或手机设置的横屏或竖屏无关的。也就是说不必做翻转屏的坐标转换。但要考虑握持手机的方向修正。