由于andorid不建议使用传统的方向传感器,建议使用加速度传感器和地磁传感器来构建方向传感器的数据,实际上主要是z轴的旋转角度。代码如下:
public class MainActivity extends Activity { private ImageView compass; private SensorManager sensorManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); compass = (ImageView) findViewById(R.id.compass); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); Sensor AccelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); sensorManager.registerListener(sensorEventListener,magneticSensor,SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(sensorEventListener,AccelerometerSensor,SensorManager.SENSOR_DELAY_GAME); } private SensorEventListener sensorEventListener = new SensorEventListener() { float[] accelerometerValues = new float[3]; float[] maneticValues = new float[3]; private float lastDegree; @Override public void onSensorChanged(SensorEvent sensorEvent) { if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER){ accelerometerValues = sensorEvent.values.clone(); }else if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){ maneticValues = sensorEvent.values.clone(); } float[] R = new float[9]; float[] values = new float[3]; SensorManager.getRotationMatrix(R,null,accelerometerValues,maneticValues); SensorManager.getOrientation(R,values);
//获取方向角度,可根据需要应用 float rotateDegree = -(float) Math.toDegrees(values[0]); if (Math.abs(rotateDegree - lastDegree) > 1){ RotateAnimation animation = new RotateAnimation(lastDegree,rotateDegree, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); animation.setFillAfter(true); compass.startAnimation(animation); lastDegree = rotateDegree; } } @Override public void onAccuracyChanged(Sensor sensor, int i) { } }; @Override protected void onDestroy() { if (sensorManager != null){ sensorManager.unregisterListener(sensorEventListener); } super.onDestroy(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }