指指指指南针
实现指南针能够旋转要求手机内部有地磁传感器和加速度传感器,然后用自定义View画出指南针。通过地磁传感器计算出的角度,通过一系列的计算将这个角度转换成合适的角度后利用自定义View中的角度的set方法来将角度传到自定义View中。在surface中开启一个线程实现指南针的动画。
传感器部分
Android中的传感器的用法其实都很类似。首先第一步要获取到SensorManager的实例
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
SensorManager是系统所有传感器的管理器,调用getDefaultSensor()方法来得到任意的传感器类型。
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Log.d("data", "magneticSensor的值:" + magneticSensor);
Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Log.d("data", "accelerometerSensor的值 : " + accelerometerSensor);
此时的magneticSensor 就代表着一个地磁传感器,accelerometerSensor 代表着一个加速度传感器。
接下来对传感器输出的信号进行监听,借助SensorEventListener来实现。SensorEventListener是一个接口,其中定义了onSensorChanged()和onAccuaryChanged()这两个方法,仔细看注释。
private SensorEventListener listener = new SensorEventListener() {
float[] accelerometerValues = new float[3];
float[] magneticValues = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
// 判断当前是加速度传感器还是地磁传感器
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 注意赋值时要调用clone()方法,不然accelerometerValues和magneticValues将会指向同一个引用。
accelerometerValues = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// 注意赋值时要调用clone()方法,不然accelerometerValues和magneticValues将会指向同一个引用。
magneticValues = event.values.clone();
}
float[] R = new float[9];
float[] values = new float[3];
// 得到一个包含旋转矩阵的R数组,第一个参数R是一个长度为9的float数组,这个方法计算出的旋转数据就会赋值到这个数组中
// ,第二个参数是一个用于将地磁向量转换成重力坐标的旋转矩阵,通常指定为null即可。
// 第三个参数和第四个参数分别就是加速度传感器和地磁传感器输出的values值。
SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);
// 计算手机的旋转数据
// values是一个长度为3的float数组,手机在各个方向上的旋转数据将会存放到这个数组当中
// ,其中values[0]记录着手机围绕Z轴的旋转角度,value[1]和values[2]分别对应X轴和Y轴,这些数据都以弧度为单位,
//