Android 传感器
/**
* Android传感器一览表
* 加速度 TYPE_ACCELEROMETER SENSOR_TYPE_ACCELEROMETER 1
* 磁力域 TYPE_MAGNETIC_FIELD SENSOR_TYPE_MAGNETIC 2
* 方向 TYPE_ORIENTATION SENSOR_TYPE_ORIENTATION 3
* 陀螺 TYPE_GYROSCOPE SENSOR_TYPE_GYROSCOPE 4
* 光线(亮度)TYPE_LIGHT SENSOR_TYPE_LIGHT 5
* 压力 TYPE_PRESSURE SENSOR_TYPE_PRESSURE 6
* 温度 TYPE_TEMPERATURE SENSOR_TYPE_TEMPERATURE 7
* 临近性 TYPE_PROXIMITY SENSOR_TYPE_PROXIMITY 8
*
* 从传感器管理器中获取其中某个或者某些传感器的方法有如下三种:
* 第一种:获取某种传感器的默认传感器
* Sensor defaultGyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
*
* 第二种:获取某种传感器的列表
* List<Sensor> pressureSensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);
*
* 第三种:获取所有传感器的列表,我们这个例子就用的第三种
* List<Sensor> allSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
*
* 对于某一个传感器,它的一些具体信息的获取方法可以见下表:
* getMaximumRange() 最大取值范围
* getName() 设备名称
* getPower() 功率
* getResolution() 精度
* getType() 传感器类型
* getVendor() 设备供应商
* getVersion() 设备版本号
*/
1、显示手机所有传感器,加速度传感器,简易微信摇一摇
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/activity_main" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 tools:context="com.example.lesson21_sensordemo.MainActivity"> 7 8 <ListView 9 android:id="@+id/lv" 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" /> 12 </RelativeLayout>
1 public class MainActivity extends AppCompatActivity { 2 3 SensorManager manager; 4 List<Sensor> sensorList; 5 Sensor accelerometerSensor;//加速度传感器 6 SoundPool pool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100); 7 int id; 8 9 ListView lv;//ListView显示当前手机所有传感器列表 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 lv = (ListView) findViewById(R.id.lv); 16 initSensor(); 17 18 //获取一个加速度传感器 19 accelerometerSensor = manager.getDefaultSensor(TYPE_ACCELEROMETER); 20 id = pool.load(this, R.raw.notify, 100); 21 22 } 23 24 private void initSensor() { 25 26 //首先获取SensorManager实例 27 manager = (SensorManager) getSystemService(SENSOR_SERVICE); 28 //获取所有传感器 29 sensorList = manager.getSensorList(TYPE_ALL); 30 31 lv.setAdapter(adapter); 32 } 33 34 //接着对传感器输出的信号进行监听 35 //微信摇一摇 36 SensorEventListener listener = new SensorEventListener() { 37 @Override 38 public void onSensorChanged(SensorEvent event) { 39 //传感器检测到数值变化时调用 40 float[] values = event.values; 41 float max = accelerometerSensor.getMaximumRange(); 42 43 float yao = max / 5 * 4; 44 float x = values[0]; 45 float y = values[1]; 46 float z = values[2]; 47 48 if (Math.abs(x) > yao || Math.abs(y) > yao || Math.abs(z) > yao) { 49 pool.play(id, 1, 1, 0, 0, 1); 50 } 51 } 52 53 @Override 54 public void onAccuracyChanged(Sensor sensor, int accuracy) { 55 /** 56 * 精度改变时调用 57 * 精度使用以下四个状态常量之一来代表: 58 * SENSOR_STATUS_ACCURACY_LOW 59 * SENSOR_STATUS_ACCURACY_MEDIUM 60 * SENSOR_STATUS_ACCURACY_HIGH 61 * SENSOR_STATUS_UNRELIABLE 62 */ 63 64 } 65 }; 66 67 @Override 68 protected void onStart() { 69 super.onStart(); 70 /** 71 * 注册监听事件 72 * 第一个参数是SensorEventListener的实例,第二个参数是Sensor的实例 73 * 第三个参数是用于表示传感器输出信息的更新速率。也即耗电量 74 * SENSOR_DELAY_UI 延迟60ms 75 * SENSOR_DELAY_NORMAL 延迟200ms 76 * SENSOR_DELAY_GAME 延迟20ms 77 * SENSOR_DELAY_FASTEST 延迟0ms 78 */ 79 80 //注册监听. 81 manager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL); 82 83 } 84 85 @Override 86 protected void onDestroy() { 87 super.onDestroy(); 88 //传感器一定要释放资源 89 manager.unregisterListener(listener); 90 } 91 92 private BaseAdapter adapter = new BaseAdapter() { 93 @Override 94 public int getCount() { 95 return sensorList.size(); 96 } 97 98 @Override 99 public Object getItem(int position) { 100 return null; 101 } 102 103 @Override 104 public long getItemId(int position) { 105 return 0; 106 } 107 108 @Override 109 public View getView(int position, View convertView, ViewGroup parent) { 110 if (convertView == null) { 111 convertView = View.inflate(getBaseContext(), android.R.layout.simple_list_item_1, null); 112 } 113 TextView tv = (TextView) convertView; 114 Sensor sensor1 = sensorList.get(position); 115 tv.setText("名字:" + sensor1.getName() + "\n类型:"); 116 117 switch (sensor1.getType()) { 118 case Sensor.TYPE_LIGHT: 119 tv.append("光传感器"); 120 break; 121 case Sensor.TYPE_PROXIMITY: 122 tv.append("接近传感器"); 123 break; 124 case Sensor.TYPE_AMBIENT_TEMPERATURE: 125 tv.append("周边温度传感器"); 126 break; 127 case Sensor.TYPE_PRESSURE: 128 tv.append("压力传感器"); 129 break; 130 case Sensor.TYPE_GYROSCOPE: 131 tv.append("陀螺仪传感器"); 132 break; 133 case Sensor.TYPE_MAGNETIC_FIELD: 134 tv.append("磁场传感器"); 135 break; 136 case Sensor.TYPE_ORIENTATION: 137 tv.append("方向传感器"); 138 break; 139 case Sensor.TYPE_GRAVITY: 140 tv.append("重力传感器"); 141 break; 142 case Sensor.TYPE_ACCELEROMETER: 143 tv.append("加速度传感器"); 144 break; 145 case Sensor.TYPE_LINEAR_ACCELERATION://API23引入 146 tv.append("线性加速传感器"); 147 break; 148 case Sensor.TYPE_GAME_ROTATION_VECTOR://API23引入 149 tv.append("旋转矢量传感器"); 150 break; 151 default: 152 tv.append("其他"); 153 break; 154 } 155 tv.append("\n提供商:" + sensor1.getVendor() + "\n耗电:" + sensor1.getPower()); 156 157 return convertView; 158 } 159 }; 160 }
2、光感传感器
/**
* 最强的光线强度(估计只有沙漠地带才能达到这个值)
* public static final float LIGHT_SUNLIGHT_MAX = 120000.0f;
* 万里无云时阳光直射的强度
* public static final float LIGHT_SUNLIGHT = 110000.0f;
* 有阳光,但被云彩抵消了部分光线时的强度
* public static final float LIGHT_SHADE = 20000.0f;
* 多云时的光线强度
* public static final float LIGHT_OVERCAST = 10000.0f;
* 太阳刚刚升起时(日出)的光线强度
* public static final float LIGHT_SUNRISE = 400.0f;
* 在阴雨天,没有太阳时的光线强度
* public static final float LIGHT_CLOUDY = 100.0f;
* 夜晚有月亮时的光线强度
* public static final float LIGHT_FULLMOON = 0.25f;
* 夜晚没有月亮时的光线强度(当然,也不能有路灯,就是漆黑一片)
* public static final float LIGHT_NO_MOON = 0.001f;
*/
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent"> 4 <TextView 5 android:id="@+id/tv_lightSensor" 6 android:layout_centerInParent="true" 7 android:layout_width="wrap_content" 8 android:layout_height="wrap_content" 9 android:textSize="24sp" 10 /> 11 12 </RelativeLayout>
1 public class LightSensorTest extends AppCompatActivity { 2 private SensorEventListener listener = new SensorEventListener() { 3 @Override 4 public void onSensorChanged(SensorEvent event) { 5 //values数组的第一个下标的值就是当前的光照强度 6 float value = event.values[0]; 7 tv_lightSensor.setText("当前亮度为:" + value + "lx");//以勒克斯为单位 8 } 9 10 @Override 11 public void onAccuracyChanged(Sensor sensor, int accuracy) { 12 13 } 14 }; 15 TextView tv_lightSensor; 16 SensorManager manager; 17 18 Sensor sensor; 19 20 @Override 21 protected void onCreate(@Nullable Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23 setContentView(R.layout.activity_lightsensor); 24 25 tv_lightSensor = (TextView) findViewById(R.id.tv_lightSensor); 26 27 manager = (SensorManager) getSystemService(SENSOR_SERVICE); 28 sensor = manager.getDefaultSensor(Sensor.TYPE_LIGHT); 29 manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL); 30 } 31 32 @Override 33 protected void onDestroy() { 34 super.onDestroy(); 35 manager.unregisterListener(listener); 36 } 37 }
3、方向传感器,简易指南针
/**
* 方向传感器
* values[0]记录着手机围绕Z轴的旋转角度,values[1]记录着手机围绕X轴的旋转角度,values[2]记录着手机围绕着Y轴额旋转角度
* Sensor.TYPE_ORIENTATION这种传感器类型,Android废弃。
* 事实上,Android获取手机旋转的方向和角度是通过加速度传感器和地磁传感器共同计算出的
*/
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent"> 4 <ImageView 5 android:id="@+id/iv" 6 android:layout_width="wrap_content" 7 android:layout_height="wrap_content" 8 android:src="@mipmap/compass" 9 android:layout_centerInParent="true"/> 10 11 </RelativeLayout>
1 public class CompassTest extends AppCompatActivity { 2 ImageView iv; 3 SensorManager manager; 4 5 @Override 6 protected void onCreate(@Nullable Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_compass); 9 iv = (ImageView) findViewById(R.id.iv); 10 11 manager = (SensorManager) getSystemService(SENSOR_SERVICE); 12 //加速度传感器 13 Sensor accelerometerSensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 14 //地磁传感器 15 Sensor magneticSensor = manager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 16 17 manager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME); 18 manager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_GAME); 19 20 } 21 22 private SensorEventListener listener = new SensorEventListener() { 23 float[] accelerometerValues = new float[3]; 24 float[] magneticValues = new float[3]; 25 private float lastRatateDegree; 26 27 @Override 28 public void onSensorChanged(SensorEvent event) { 29 //判断当前是加速度传感器还是地磁传感器 30 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 31 //注意这里一定要是用values数组的clone()方法,否则accelerometerValues和magneticValues将指向同一个引用 32 accelerometerValues = event.values.clone(); 33 } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 34 magneticValues = event.values.clone(); 35 } 36 //然后将这个两个值传入到SensorManager的getRotationMatrix()方法中就可以得到一个包含旋转矩阵的R数组 37 float[] R = new float[9]; 38 float[] values = new float[3]; 39 40 41 manager.getRotationMatrix(R, null, accelerometerValues, magneticValues);//为R数组赋值 42 manager.getOrientation(R, values);//为values数组赋值 43 44 //现在values中就已经包含手机在所有方向上旋转的弧度了。其中values[0]表示手机围绕Z轴旋转的弧度。 45 //调用Math.toDegress()方法将它转成角度 46 Log.e("TAG", "values[0] is " + Math.toDegrees(values[0])); 47 48 //values[0]取值范围是-180到180度,其中±180度表示正南方向,0度表示正北方向,-90度表示正西方向,90度表示正东方向 49 50 //将计算出的旋转角度取反,用于旋转指南针背景图 51 float rotateDegree = -(float) Math.toDegrees(values[0]); 52 if (Math.abs(rotateDegree - lastRatateDegree) > 1) { 53 RotateAnimation animation = new RotateAnimation(lastRatateDegree, rotateDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 54 animation.setDuration(500); 55 animation.setFillAfter(true); 56 iv.startAnimation(animation); 57 lastRatateDegree = rotateDegree; 58 } 59 60 61 } 62 63 @Override 64 public void onAccuracyChanged(Sensor sensor, int accuracy) { 65 66 } 67 }; 68 69 @Override 70 protected void onDestroy() { 71 super.onDestroy(); 72 if (manager != null) { 73 manager.unregisterListener(listener); 74 manager = null; 75 } 76 } 77 }