方向传感器
方向传感器的使用:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
可以通过以上的方法获取方向传感器,可以安卓早就废弃了这个传感器类型,虽然代码还是有效的,但已经不再推荐这么写了。
事实上,Android获取手机旋转的方向和角度是通过加速度传感器和地磁传感器共同计算得出的,这也是 Android 目
前推荐使用的方式。
将加速度传感器与地磁传感器的数据转化为方向数据的关键:
1.得到一个包含旋转矩阵的r数组
SensorManager.getRotationMatrix(r, null, acceValues, magneticValues);
2.将r的结果传入,获取方向结果
SensorManager.getOrientation(r, values);//计算手机的旋转数据
values是一个长度为 3 的 float 数组,手机在各个方向上的旋转数据都会被存放到这个数组当中。
注意这里计算出的数据都是以弧度为单位的,因此如果你想将它们转换成角度还需要调
用如下方法:Math.toDegrees(values[0]);
values[0]的取值范围是:180 度到 180 度,
其中±180 度表示正南方向,0 度表示正北方向,90 度表示正西方向,90 度表示正东方向。
代码如下:
//通过加速度传感器与地磁传感器获取方向 public class OrientationDemo extends Activity { private TextView tv; private SensorManager sensorManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.accelerometer_layout); tv = (TextView) findViewById(R.id.tv_acc);//显示传感器的结果 //获取传感器管理者 SensorManager sensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE); //获取加速度传感器对象 Sensor accSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //获取地磁传感器对象 Sensor magnSensorr=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); //给上面两个传感器设置监听,GAME的速率比标准的快点 sensorManager.registerListener(listener, accSensor, SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(listener, magnSensorr, SensorManager.SENSOR_DELAY_GAME); } private SensorEventListener listener=new SensorEventListener() { //注意:这两个数组必须放在onSensorChanged的外面,否则计算出来的结果为0 float[] acceValues=new float[3];//存放加速度数据 float[] magneticValues=new float[3];//存放地磁传感器数据 在该处定义指南位置的记录 @Override public void onSensorChanged(SensorEvent event) { //判断当前是加速度传感器还是地磁传感器 if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){ acceValues=event.values.clone();//clone的作用为复制数组 //Toast.makeText(getApplicationContext(), "地磁:"+acceValues[0], 0).show(); }else if(event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){ magneticValues=event.values.clone(); Toast.makeText(getApplicationContext(), "地磁:"+magneticValues[0], 0).show(); }//注意在赋值的时候一定要调用一下 values 数组的 clone()方法,不 //然 acceValues和 magneticValues将会指向同一个引用。 float[] r=new float[9];//getRotationMatrix()方法计算出的旋转数据赋值到这个数组当中 float[] values=new float[3];//存放旋转的方向数据 SensorManager.getRotationMatrix(r, null, acceValues, magneticValues); SensorManager.getOrientation(r, values);//获取手机的旋转数据 tv.setText("方向绕Z轴:"+values[0]+"幅度 "+Math.toDegrees(values[0])+"°" +"\n方向绕X轴:"+values[1]+"幅度 "+Math.toDegrees(values[1])+"度" +"\n方向绕Y轴:"+values[2]+"幅度 "+Math.toDegrees(values[2])+"°"); /* toDegrees方法的作用为将幅度转换成角度,values[0]的取值范围是:180 度到-180度,也代表手机屏幕上方与正北方向的夹角 其中±180度表示正南方向,0 度表示正北方向,-90度表示正西方向,90度表示正东方向。指南代码见下 .........放入指南代码*/ } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; @Override protected void onDestroy() { super.onDestroy(); if(sensorManager!=null){ sensorManager.unregisterListener(listener); } } }
那么假设有张图片如下:
将该图片显示到屏幕上,北朝着手机屏幕上方,并且假设这时的北所指方向为实际的北,那么当手机顺时针旋转了90度后北就指到了东的位置,那么想要将北指向北,就需要这张图片逆时针旋转90度,定义图片指南的代码如下:
// 将计算出的旋转角度取反,用于旋转指南针背景图 float rotateDegree = -(float) Math.toDegrees(values[0]); if (Math.abs(rotateDegree - lastRotateDegree) > 1) { RotateAnimation animation = new RotateAnimation (lastRotateDegree, rotateDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setFillAfter(true);//停留在旋转后的状态 compassImg.startAnimation(animation); lastRotateDegree = rotateDegree;//记录下当前旋转的位置 }
lastRotateDegree需要在该方法外面定义