光照传感器

Android 中每个传感器的用法其实都比较类似,真的可以说是一通百通了。首先第一步要获取到 SensorManager 的实例

[html] view plain copy
  1. SensorManager senserManager = (SensorManager)
  2. getSystemService(Context.SENSOR_SERVICE);

SensorManager 是系统所有传感器的管理器,有了它的实例之后就可以调用getDefaultSensor()方法来得到任意的传感器类型了

[html] view plain copy
  1. Sensor sensor = senserManager.getDefaultSensor(Sensor.TYPE_LIGHT);

接下来我们需要对传感器输出的信号进行监听,这就要借助 SensorEventListener 来实现了。SensorEventListener 是一个接口,其中定义了 onSensorChanged()和onAccuracyChanged()这两个方法

[html] view plain copy
  1. SensorEventListener listener = new SensorEventListener() {
  2. @Override
  3. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  4. }
  5. @Override
  6. public void onSensorChanged(SensorEvent event) {
  7. }
  8. };

当传感器的精度发生变化时就会调用 onAccuracyChanged()方法,当传感器监测到的数值发生变化时就会调用 onSensorChanged()方法。可以看到 onSensorChanged()
方法中传入了一个 SensorEvent 参数,这个参数里又包含了一个 values 数组,所有传感器输出的信息都是存放在这里的。下 面 我 们 还 需 要 调 用 SensorManager 的 registerListener() 方 法 来 注 册SensorEventListener 才能使其生效,registerListener()方法接收三个参数,第一个参数就是 SensorEventListener 的实例,第二个参数是 Sensor 的实例,这两个参数我们在前面都已经成功得到了。第三个参数是用于表示传感器输出信息的更新速率SENSOR_DELAY_UI 、 SENSOR_DELAY_NORMAL 、 SENSOR_DELAY_GAME 和SENSOR_DELAY_FASTEST 这四种值可选,它们的更新速率是依次递增的

[html] view plain copy
  1. senserManager.registerListener(listener, senser, SensorManager.SENSOR_DELAY_NORMAL);

另外始终要记得, 当程序退出或传感器使用完毕时, 一定要调用 unregisterListener ()方法将使用的资源释放掉

[html] view plain copy
  1. sensorManager.unregisterListener(listener);

代码:

[html] view plain copy
  1. public class MainActivity extends Activity {
  2. SensorManager sensorManager;
  3. TextView light;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. light=(TextView) findViewById(R.id.textView1);
  9. sensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
  10. Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
  11. sensorManager.registerListener(null, sensor, SensorManager.SENSOR_DELAY_NORMAL);
  12. }
  13. @Override
  14. protected void onDestroy() {
  15. // TODO Auto-generated method stub
  16. super.onDestroy();
  17. if (sensorManager!=null) {
  18. sensorManager.unregisterListener(listener);
  19. }
  20. }
  21. private SensorEventListener listener=new SensorEventListener() {
  22. @Override
  23. public void onSensorChanged(SensorEvent arg0) {
  24. // TODO Auto-generated method stub
  25. // values数组中第一个下标的值就是当前的光照强度
  26. float value=arg0.values[0];
  27. light.setText("Current light level is"+value+"lx");
  28. }
  29. @Override
  30. public void onAccuracyChanged(Sensor arg0, int arg1) {
  31. // TODO Auto-generated method stub
  32. }
  33. };

现在运行一下程序, 你将会在手机上看到当前环境下的光照强度, 根据所处环境的不同,显示的数值有可能是几十到几百勒克斯。而如果你使用强光来照射手机的话,就有可能会达到上千勒克斯的光照强度

加速度传感器:

第一, 获取 Sensor 实例的时候要指定一个加速度传感器的常量, 如下所示:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
第二,加速度传感器输出的信息同样也是存放在 SensorEvent 的 values 数组中的,只不过此时的 values 数组中会有三个值,分别代表手机在 X 轴、Y 轴和 Z 轴方向上的加速度信息。X 轴、Y 轴、Z 轴在空间坐标系上的含义需要注意的是,由于地心引力的存在,你的手机无论在世界上任何角落都会有一个重力加速度,这个加速度的值大约是 9.8m/s
2 。当手机平放的时候,这个加速度是作用在 Z 轴上的,当手机竖立起来的时候,这个加速度是作用在 Y 轴上的,当手机横立起来的时候,这个加速度是作用在 X 轴上的

模仿微信摇一摇

[html] view plain copy
  1. package com.example.yaoyiyao;
  2. import android.hardware.Sensor;
  3. import android.hardware.SensorEvent;
  4. import android.hardware.SensorEventListener;
  5. import android.hardware.SensorManager;
  6. import android.os.Bundle;
  7. import android.app.Activity;
  8. import android.content.Context;
  9. import android.view.Menu;
  10. import android.widget.Toast;
  11. public class MainActivity extends Activity {
  12. private SensorManager sensorManager;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. sensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
  18. Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  19. sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
  20. }
  21. @Override
  22. protected void onDestroy() {
  23. // TODO Auto-generated method stub
  24. super.onDestroy();
  25. if (sensorManager!=null) {
  26. sensorManager.unregisterListener(sensorEventListener);
  27. }
  28. }
  29. private SensorEventListener sensorEventListener=new SensorEventListener() {
  30. @Override
  31. public void onSensorChanged(SensorEvent arg0) {
  32. // TODO Auto-generated method stub
  33. // 加速度可能会是负值,所以要取它们的绝对值
  34. float xValue=Math.abs(arg0.values[0]);
  35. float yValue=Math.abs(arg0.values[1]);
  36. float zValue=Math.abs(arg0.values[2]);
  37. if (xValue>15||yValue>15||zValue>15) {
  38. // 认为用户摇动了手机,触发摇一摇逻辑
  39. Toast.makeText(MainActivity.this, "摇一摇",
  40. Toast.LENGTH_SHORT).show();
  41. }
  42. }
  43. @Override
  44. public void onAccuracyChanged(Sensor arg0, int arg1) {
  45. // TODO Auto-generated method stub
  46. }
  47. };
  48. }

方向传感器:

我们需要获取到一个用于表示方向传感器的 Sensor 实例

[html] view plain copy
  1. Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

之后在 onSensorChanged()方法中通过 SensorEvent 的 values 数组,就可以得到传感器输出的所有值了。 方向传感器会记录手机在所有方向上的旋转角度

其中,values[0]记录着手机围绕 Z 轴的旋转角度,values[1] 记录着手机围绕 X 轴的旋转角度,values[2] 记录着手机围绕 Y 轴的旋转角度

看起来很美好是吗?但遗憾的是, Android早就废弃了Sensor.TYPE_ORIENTATION这种传感器类型,虽然代码还是有效的,但已经不再推荐这么写了。事实上,Android 获
取手机旋转的方向和角度是通过加速度传感器和地磁传感器共同计算得出的,这也是Android 目前推荐使用的方式。首先我们需要分别获取到加速度传感器和地磁传感器的实例,并给它们注册监听器

[html] view plain copy
  1. Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.
  2. TYPE_ACCELEROMETER);
  3. Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.
  4. TYPE_MAGNETIC_FIELD);
  5. sensorManager.registerListener(listener, accelerometerSensor,
  6. SensorManager.SENSOR_DELAY_GAME);
  7. sensorManager.registerListener(listener, magneticSensor,
  8. SensorManager.SENSOR_DELAY_GAME);

由于方向传感器的精确度要求通常都比较高, 这里我们把传感器输出信息的更新速率提高了一些,使用的是 SENSOR_DELAY_GAME。接下来在 onSensorChanged()方法中可以获取到 SensorEvent 的 values 数组,分别记录着加速度传感器和地磁传感器输出的值。然后将这两个值传入到 SensorManager的 getRotationMatrix()方法中就可以得到一个包含旋转矩阵的 R 数组

[html] view plain copy
  1. SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);

其中第一个参数 R 是一个长度为 9 的 float 数组,getRotationMatrix()方法计算出的旋转数据就会赋值到这个数组当中。 第二个参数是一个用于将地磁向量转换成重力坐标的旋
转矩阵,通常指定为 null 即可。第三和第四个参数则分别就是加速度传感器和地磁传感器输出的 values 值。得到了 R 数组之后,接着就可以调用 SensorManager 的 getOrientation()方法来计算手机的旋转数据了

[html] view plain copy
  1. SensorManager.getOrientation(R, values)

alues 是一个长度为 3 的 float 数组,手机在各个方向上的旋转数据都会被存放到这个数组当中。其中 values[0]记录着手机围绕着图 12.3 中 Z 轴的旋转弧度,values[1]记录
着手机围绕 X 轴的旋转弧度,values[2]记录着手机围绕 Y 轴的旋转弧度。注意这里计算出的数据都是以弧度为单位的, 因此如果你想将它们转换成角度还需要调用如下方法:
Math.toDegrees(values[0]);

简易指南针

[html] view plain copy
  1. package com.example.zhinanzhen;
  2. import android.hardware.Sensor;
  3. import android.hardware.SensorEvent;
  4. import android.hardware.SensorEventListener;
  5. import android.hardware.SensorManager;
  6. import android.os.Bundle;
  7. import android.app.Activity;
  8. import android.content.Context;
  9. import android.util.Log;
  10. import android.view.Menu;
  11. public class MainActivity extends Activity {
  12. private SensorManager sensorManager;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. sensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
  18. //磁性传感器
  19. Sensor magmagneticSensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
  20. //加速度传感器
  21. Sensor accelerometerSensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  22. sensorManager.registerListener(listener, magmagneticSensor, SensorManager.SENSOR_DELAY_GAME);
  23. }
  24. @Override
  25. protected void onDestroy() {
  26. // TODO Auto-generated method stub
  27. super.onDestroy();
  28. if (sensorManager!=null) {
  29. sensorManager.unregisterListener(listener);
  30. }
  31. }
  32. private SensorEventListener listener=new SensorEventListener() {
  33. float[] accelerometerValues = new float[3];
  34. float[] magneticValues = new float[3];
  35. @Override
  36. public void onSensorChanged(SensorEvent arg0) {
  37. // TODO Auto-generated method stub
  38. // 判断当前是加速度传感器还是地磁传感器
  39. if (arg0.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
  40. // 注意赋值时要调用clone()方法
  41. accelerometerValues = arg0.values.clone();
  42. } else if (arg0.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
  43. // 注意赋值时要调用clone()方法
  44. magneticValues = arg0.values.clone();
  45. }
  46. float[] R = new float[9];
  47. float[] values = new float[3];
  48. SensorManager.getRotationMatrix(R, null, accelerometerValues,
  49. magneticValues);
  50. SensorManager.getOrientation(R, values);
  51. Log.d("MainActivity", "value[0] is " + Math.toDegrees(values[0]));
  52. }
  53. @Override
  54. public void onAccuracyChanged(Sensor arg0, int arg1) {
  55. // TODO Auto-generated method stub
  56. }
  57. };
  58. }

如果当前 SensorEvent 中包含的是加速度传感器,就将 values 数组赋值给 accelerometerValues 数组,如果当前 SensorEvent 中包含的是地磁传感器,就将
values 数组赋值给 magneticValues 数组。注意在赋值的时候一定要调用一下 values 数组的 clone()方法, 不然 accelerometerValues 和 magneticValues 将会指向同一个引用。接下来我们分别创建了一个长度为 9 的 R 数组和一个长度为 3 的 values 数组, 然后调用 getRotationMatrix()方法为 R 数组赋值,再调用 getOrientation()方法为 values 数组赋值,这时 values 中就已经包含手机在所有方向上旋转的弧度了。其中 values[0]表示手机围绕 Z 轴旋转的弧度,这里我们调用 Math.toDegrees()方法将它转换成角度,并打印出来。现在运行一下程序,并围绕 Z 轴旋转手机,旋转的角度就会源源不断地在 LogCat 中打印出来了

alues[0]的取值范围是- 180 度到 180 度,其中±180 度表示正南方向,0 度表示正北方向,- 90 度表示正西方向,90 度表示正东方向。虽然目前我们已经得到了这些数值, 但是想要通过它们来判断手机当前的方向显然是一件伤脑筋的事情,因此我们还要想办法将当前的方向直观地显示出来。毫无疑问,最直观的方式当然是通过罗盘和指针来进行显示了,那么下面我们就来继续完善 CompassTest这个项目。这里我事先准备好了两张图片 compass.png 和 arrow.png,分别用于作为指南针的

[html] view plain copy
  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/compass_img"
  6. android:layout_width="250dp"
  7. android:layout_height="250dp"
  8. android:layout_centerInParent="true"
  9. android:src="@drawable/compass" />
  10. <ImageView
  11. android:id="@+id/arrow_img"
  12. android:layout_width="60dp"
  13. android:layout_height="110dp"
  14. android:layout_centerInParent="true"
  15. android:src="@drawable/arrow" />
  16. </RelativeLayout>
[html] view plain copy
  1. public class MainActivity extends Activity {
  2. private SensorManager sensorManager;
  3. private ImageView compassImg;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. compassImg = (ImageView) findViewById(R.id.compass_img);
  9. ⋯⋯
  10. }
  11. ⋯⋯
  12. private SensorEventListener listener = new SensorEventListener() {
  13. float[] accelerometerValues = new float[3];
  14. float[] magneticValues = new float[3];
  15. private float lastRotateDegree;
  16. @Override
  17. public void onSensorChanged(SensorEvent event) {
  18. // 判断当前是加速度传感器还是地磁传感器
  19. if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
  20. // 注意赋值时要调用clone()方法
  21. accelerometerValues = event.values.clone();
  22. } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
  23. // 注意赋值时要调用clone()方法
  24. magneticValues = event.values.clone();
  25. }
  26. float[] values = new float[3];
  27. float[] R = new float[9];
  28. SensorManager.getRotationMatrix(R, null, accelerometerValues,
  29. magneticValues);
  30. SensorManager.getOrientation(R, values);
  31. // 将计算出的旋转角度取反,用于旋转指南针背景图
  32. float rotateDegree = -(float) Math.toDegrees(values[0]);
  33. if (Math.abs(rotateDegree - lastRotateDegree) > 1) {
  34. 第 12 章 Android 特色开发,使用传感器
  35. 473
  36. RotateAnimation animation = new RotateAnimation (lastRotateDegree,
  37. rotateDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f);
  38. animation.setFillAfter(true);
  39. compassImg.startAnimation(animation);
  40. lastRotateDegree = rotateDegree;
  41. }
  42. }
  43. ⋯⋯
  44. };
  45. }

这里首先我们在 onCreate()方法中获取到了 ImageView 的实例,它是用于显示指南针的背景图的。然后在 onSensorChanged()方法中使用到了旋转动画技术,我们创建了一
个 RotateAnimation 的实例,并给它的构造方法传入了六个参数,第一个参数表示旋转的起始角度,第二个参数表示旋转的终止角度,后面四个参数用于指定旋转的中心点。这里我们把从传感器中获取到的旋转角度取反,传递给 RotateAnimation,并指定旋转的中心点为指南针背景图的中心,然后调用 ImageView 的 startAnimation ()方法来执行旋转动画。好了,代码就是这么多,现在我们重新运行一下程序,然后随意旋转手机,指南针的背景图也会跟着一起转动

转载于:https://www.cnblogs.com/dubo-/p/7711036.html

SensorManager相关推荐

  1. Android 磁场传感器 地磁倾角计算 SensorManager.getInclination方法

    需要先阅读: http://blog.csdn.net/pw4work/article/details/72784417 什么是地磁倾角呢 看图比较明显了,简单的说,就是看地磁场和水平面的的角度是多少 ...

  2. 传感器SensorManager

    光照传感器 Android 中每个传感器的用法其实都比较类似,真的可以说是一通百通了.首先第一步要获取到 SensorManager 的实例 SensorManager senserManager = ...

  3. Android中如何检测重力感应变化:Sensor和SensorManager

    在实际开发中我遇到一个让人很蛋疼的问题,大致是当我点击某一个按钮的时候,强制切换为横屏显示,这个很容易做到,只需在onclick里面调用setRequestedOrientation(Activity ...

  4. Android Manager之SensorManager(传感器)—方向传感器(Orientation sensor)

    本章节讲述方向传感器(Orientation sensor)的相关使用. 如果您还不了解传感器的相关知识,请点击:Android Manager之SensorManager(传感器)-基础知识 1.方 ...

  5. android 获取设备旋转角度,获取Android设备的方向,Sensor和SensorManager实现手机旋转角度...

    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1009/425.html 带有g-sensor的Android设备上可通过API ...

  6. Android Senor Framework (五) SensorManager

    SensorManager 通过前面的博客介绍可知在Java application中, 由SystemSensorManage对象管理每一个sensor: 在msm8909平台的HAL sensor ...

  7. Android SensorManager学习

    SensorManager 在SensorManager.java文件的开头,有一段sensor应用的示例.应用层获取sensor的数据主要是通过SensorManager的onAccuracyCha ...

  8. 在 Android 应用程序中使用 SQLite 数据库以及怎么用

    part one : android SQLite 简单介绍 SQLite 介绍 SQLite 一个非常流行的嵌入式数据库.它支持 SQL 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...

  9. [Android]开发摇一摇分歧表决器过程

    心血来潮,走进Android,准备开发一个摇一摇分歧表决器(PS:这个想法源自去年看的一个都市剧<约会专家>中主人公杭杭开发的分歧表决器APP). 简述:摇一摇分歧表决器是一款Androi ...

最新文章

  1. 导出excel 数字前少0_【产品介绍】数字压力校验仪
  2. ****题(alb)
  3. 学习 TTreeView [15] - 连接数据库 (作为给 丁永其 和 DELPHI万岁 两位朋友的回复)...
  4. axios04-文件上传
  5. 如何在CSDN博客中显示图片而不是链接
  6. 【laravel5.4】迁移文件的生成、修改、删除
  7. 重读经典:《ImageNet Classification with Deep Convolutional Neural Networks》
  8. android 视网膜黄斑检查 amsler,自测黄斑病变 | 一张图搞定
  9. wkhtmltopdf网页转PDF程序安装教程
  10. 为什么会有宇宙?宇宙之外会有什么?
  11. tcp压测工具_使用BeetleX的TcpBenchmark工具进行百万设备模拟测试
  12. vue-happy-scroll:vue中借助vue happy scroll实现局部文字滚动
  13. /proc/meminfo 文件
  14. Django学习(二)
  15. 关于使用VS.Net2003调试器出现的问题及相关解决方法[转]
  16. 项目管理十大知识领域之项目相关方管理
  17. ttest函数使用方法_TTEST 函数 - EXCEL 2010 中文帮助文档
  18. 人工智能真正值得担心的是缺德,而不是聪明
  19. 搜狗输入法取消英文空格确认
  20. arcgis里dem填洼_ArcGIS水文分析实战教程(4)地形预处理

热门文章

  1. 现在都用微信,支付宝付款,没有现金,要是没有网络,该怎么办?
  2. 员工不愿意被调岗, 怎么办?
  3. 1956年五元钱币市值多少?
  4. 支付宝芝麻分多少算正常?分高有什么好处?
  5. 为什么很多人认为一辆车开五六年就要换车?
  6. 狐假虎威的故事,狐假虎威的故事告诉我们什么道理?
  7. 教大家一个简单的办法
  8. 想赚钱,赚大钱,必须要有商业思维
  9. 实体经济的“数字化”是不可逆转的趋势
  10. 没有钱的男人和有钱的男人区别在哪里?