SensorCompass

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>

MainActivity.java

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) {

		}
	};
}


你可能感兴趣的:(SensorCompass)