activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/compass_img" android:layout_width="250dp" android:layout_height="250dp" android:layout_centerInParent="true" android:src="@drawable/compass" /> <ImageView android:id="@+id/arrow_img" android:layout_width="60dp" android:layout_height="110dp" android:layout_centerInParent="true" android:src="@drawable/arrow" /> </RelativeLayout>
package com.example.compasstest; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.ImageView; /** * 完成一个简易指南针的功能 1. 方向感应由磁力感应器与加速感应器共同实现 2. SensorManager: 得到旋转数据: getRotationMatrix(float[] R, float[] I, float[] gravity, float[] geomagnetic) 第一个就是我们需要填充的R数组,大小是9 第二个是是一个转换矩阵,将磁场数据转换进实际的重力坐标中 一般默认情况下可以设置为null 第三个是一个大小为3的数组,表示从磁场感应器获取来的数据 第四个是一个大小为3的数组,表示从加速度感应器获取来的数据 得到旋转角度数据: getOrientation(float[] R, float values[]) 第一个是前面计算出的R 第二个是计算出的旋转角度数据, values[0]: 为围绕Z轴的旋转角度, 但需要通过Math.toDegree()转换一下 */ public class MainActivity extends Activity { // 得到传感器管理器 private SensorManager sensorManager; // 指南针盘面 private ImageView compassImg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取盘面 compassImg = (ImageView) findViewById(R.id.compass_img); // 获取传感器管理器-得到系统服务(传感器服务) sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // 得到传感器对象(磁场感应检测) Sensor magneticSensor = sensorManager .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); // 得到传感器对象(加速度感应检测) Sensor accelerometerSensor = sensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 第一个参数:监听Sensor事件,第二个参数是Sensor目标种类的值,第三个参数是延迟时间的精度密度(收集数据的时间间隔) sensorManager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onDestroy() { super.onDestroy(); if (sensorManager != null) { sensorManager.unregisterListener(listener); } } /* * 监听事件 */ private SensorEventListener listener = new SensorEventListener() { // 磁场感应值-3个值 private float[] magValues = new float[3]; // 加速度感应值-3个值 private float[] accValues = new float[3]; // 当前旋转的角度 private float currentDegree = 0; // 传感器变化 @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { // 得到磁场感应值 magValues = event.values.clone(); } else if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { // 得到加速度感应值 accValues = event.values.clone(); } // 得到旋转数据 float[] R = new float[9]; SensorManager.getRotationMatrix(R, null, magValues, accValues); // 得到旋转角度数据 float[] degreevalues = new float[3]; SensorManager.getOrientation(R, degreevalues); // 得到旋转的角度--values[0]: 为围绕Z轴的旋转角度, float degree = (float) Math.toDegrees(degreevalues[0]); // 如果旋转的角度值大于1度 if (Math.abs(degree - currentDegree) > 1) { // 旋转罗盘-启动动画(围绕圆心旋转) RotateAnimation animation = new RotateAnimation(currentDegree, degree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setFillAfter(true); compassImg.startAnimation(animation); // 更新当前旋转的角度 currentDegree = degree; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; }