关于Android传感器

最近项目需要各种手机传感器,于是就此来写个总结,以此留痕。
在Android开发中,会用到各种传感器,但不一定每个真机都支持这些传感器。所以相关开发还要根据真机的实际情况来做开发。
1 获取手机的传感器
通过实例化SensorManager可以获取到手机的传感器集合

//实例化
mSensorManger= (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensorList = mSensorManger.getSensorList(Sensor.TYPE_ALL);

获取到的传感器名称:
Accelerometer 加速计
Magnetometer 磁力计
Gyroscope 陀螺仪
Proximity Sensor 近距离传感器
Ambient Light Sensor 环境光传感器
Barometer Sensor 气压计
Temperature Sensor 温度传感器
Gravity 重力
Linear Acceleration 线性加速度
Rotation Vector 旋转矢量
Step Detector 步数探测器
Step Counter 计步器
Significant Motion Detector 运动检测器
Game Rotation Vector 游戏旋转矢量
Geomagnetic Rotation Vector 地磁旋转矢量
Orientation 方向
Basic Gestures 基本手势
Motion Accel 运动加速度

Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器、环境(Environmental)传感器、位置(Position)传感器。
(1)动作传感器
这类传感器在三个轴(x、y、z)上测量加速度和旋转角度。包括如下几个传感器:

加速(accelerometer)传感器、重力(gravity)传感器、陀螺仪(gyroscope)传感器、旋转向量(rotational vector )传感器
下面来看一下传感器世界的坐标系:
[图片上传失败...(image-a8a3de-1567500246575)]
(2)环境传感器
这类传感器可以测量不同环境的参数,例如,周围环境的空气温度和压强、光照强度和湿度。包括如下几个传感器:

湿度(barometer)传感器、光线(photometer)传感器、温度(thermometer)传感器

(3)位置传感器
这类传感器可以测量设备的物理位置。包括如下几个传感器:

方向(orientation)传感器、磁力(magnetometer)传感器
了解后我们就开始进入传感器的编程工作了,接下来我们看一下Android为我们提供的传感器框架(Android sensor framework,简称ASF)。
2.Android传感器框架
Android SDK为我们提供了ASF,可以用来访问当前Android设备内置的传感器。ASF提供了很多类和接口,帮助我们完成各种与传感器有关的任务。例如:

1)确定当前Android设备内置了哪些传感器。
2)确定某一个传感器的技术指标。
3)获取传感器传回来的数据,以及定义传感器回传数据的精度。
4)注册和注销传感器事件监听器,这些监听器用于监听传感器的变化,通常从传感器回传的数据需要利用这些监听器完成。
ASF允许我们访问很多传感器类型,这些传感器有一些是基于硬件的传感器,还有一些是基于软件的传感器。基于硬件的传感器就是直接以芯片形式嵌入到Android设备中,这些传感器直接从外部环境获取数据。基于软件的传感器并不是实际的硬件芯片,基于软件的传感器传回的数据本质上也来自于基于硬件的传感器,只是这些数据通常会经过二次加工。所以基于软件的传感器也可以称为虚拟(virtual)传感器或合成(synthetic)传感器。

Android对每个设备的传感器都进行了抽象,其中SensorManger类用来控制传感器,Sensor用来描述具体的传感器,SensorEventListener用来监听传感器值的改变。
(1)SensorManager类
用于创建sensor service的实例。该类提供了很多用于访问和枚举传感器,注册和注销传感器监听器的方法。而且还提供了与传感器精度、扫描频率、校正有关的常量。
(2)Sensor类
Sensor类为我们提供了一些用于获取传感器技术参数的方法。如版本、类型、生产商等。例如所有传感器的TYPE类型如下:
注意:1-8是硬件传感器,9是软件传感器,其中方向传感器的数据来自重力和磁场传感器,10-12是硬件或软件传感器。
序号|传感器|Sensor类中定义的TYPE常量
|:-- :|:--:| :-----:| :--:|
啊|as|as

序号 传感器 Sensor类中定义的TYPE常量
1 加速度传感器 TYPE_ACCELEROMETER
2 温度传感器 TYPE_AMBIENT_TEMPERATURE
3 陀螺仪传感器 TYPE_GYROSCOPE
4 光线传感器 TYPE_LIGHT
5 磁场传感器 TYPE_MAGNETIC_FIELD
6 压力传感器 TYPE_PRESSURE
7 临近传感器 TYPE_PROXIMITY
8 湿度传感器 TYPE_RELATIVE_HUMIDITY
9 方向传感器 TYPE_ORIENTATION
10 重力传感器 TYPE_GRAVITY
11 线性加速传感器 TYPE_LINEAR_ACCELERATION
12 旋转向量传感器 TYPE_ROTATION_VECTOR

(3)SensorEvent类
系统使用该类创建传感器事件对象。该对象可以提供与传感器事件有关的信息。传感器事件对象包括的信息有原始的传感器回传数据、传感器类型、数据的精度以及触发事件的时间。
(4)SensorEventListener接口
该接口包含两个回调方法,当传感器的回传值或精度发生变化时,系统会调用这两个回调方法。

/**
 * 传感器精度变化时回调
 */
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
 * 传感器数据变化时回调
 */
@Override
public void onSensorChanged(SensorEvent event) {
}

到了这里,我们就可以进行传感器开发工作了。
3.获取传感器技术参数
下来我们编写代码来获取一下自己手机的传感器技术参数。

TextView tvSensors = (TextView) findViewById(R.id.tv_sensors);
//获取传感器SensorManager对象
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : sensors) {
  tvSensors.append(sensor.getName() + "\n");
}

先运行一下看看效果:
[图片上传失败...(image-a87622-1567500246575)]
貌似我的手机传感器还不少,哈哈。注意此处必须用实体机测试哦。

下来我们分别看一下动作传感器、环境传感器和位置传感器的组成及使用方法。
4.动作传感器的组成及使用方法
所有的动作传感器都会返回三个浮点数的值(通过长度为3的数组返回),但对于不同的传感器,这三个只是意义不同。例如,对于加速传感器,会返回三个坐标轴的数据。对于陀螺仪传感器,会返回三个坐标轴的旋转角速度。

注意:动作传感器本身一般并不会用于监测设备的位置,关于设备的位置需要用其他类型的传感器进行监测,例如,磁场传感器。
(1)加速度传感器
加速度传感器需要结合重力传感器使用,以减少加速度受重力的影响。首先需要实现SensorEventListener接口,添加回调方法,然后获取传感器SensorManager对象,注册传感器,然后我们就可以监听传感器的变化了。示例代码如下:

public class SensorActivity extends AppCompatActivity implements SensorEventListener {
  private TextView tvAccelerometer;
  private SensorManager mSensorManager;
  private float[] gravity = new float[3];
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sensor);
    tvAccelerometer = (TextView) findViewById(R.id.tv_accelerometer);
    //获取传感器SensorManager对象
    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
  }
  /**
   * 传感器精度变化时回调
   */
  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
  }
  /**
   * 传感器数据变化时回调
   */
  @Override
  public void onSensorChanged(SensorEvent event) {
    //判断传感器类别
    switch (event.sensor.getType()) {
      case Sensor.TYPE_ACCELEROMETER: //加速度传感器
        final float alpha = (float) 0.8;
        gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
        gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
        gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
 
        String accelerometer = "加速度传感器\n" + "x:"
            + (event.values[0] - gravity[0]) + "\n" + "y:"
            + (event.values[1] - gravity[1]) + "\n" + "z:"
            + (event.values[2] - gravity[2]);
        tvAccelerometer.setText(accelerometer);
        //重力加速度9.81m/s^2,只受到重力作用的情况下,自由下落的加速度
        break;
      case Sensor.TYPE_GRAVITY://重力传感器
        gravity[0] = event.values[0];//单位m/s^2
        gravity[1] = event.values[1];
        gravity[2] = event.values[2];
        break;
      default:
        break;
    }
  }
  /**
   * 界面获取焦点,按钮可以点击时回调
   */
  protected void onResume() {
    super.onResume();
    //注册加速度传感器
    mSensorManager.registerListener(this,
        mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),//传感器TYPE类型
        SensorManager.SENSOR_DELAY_UI);//采集频率
    //注册重力传感器
    mSensorManager.registerListener(this,
        mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
        SensorManager.SENSOR_DELAY_FASTEST);
  }
  /**
   * 暂停Activity,界面获取焦点,按钮可以点击时回调
   */
  @Override
  protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
  }
 
}

我们将手机水平正面朝上放置于桌子上,看一下效果图:
[图片上传失败...(image-9ac78f-1567500246575)]
我们可以看到正值和负值,那什么情况是正值?什么情况是负值呢?

设备沿x轴正方向推动,x轴加速度为正值。
设备沿y轴正方向推动,y轴加速度为正值。
如果沿z轴正方向推动,此时手机相对于桌子水平正面朝上放置,z轴加速度为正值。由底部朝着顶部以a m/s^2的加速度推动,那么z轴的加速度为a + 9.81,所以如果计算实际的加速度(抵消重力加速度),需要减9.81。

5.位置传感器的组成及使用方法
Android提供了磁场传感器和方向传感器用于确定设备的位置,还提供了测量设备正面到某一个邻近物体距离的传感器(邻近传感器)。

邻近传感器在手机中很常见。像接听电话时手机屏幕灭屏就是使用的邻近传感器。方向传感器是基于软件的,该传感器的回传数据来自加速度传感器和磁场传感器。

位置传感器对于确定设备在真实世界中的物理位置非常有用。例如,可以组合磁场传感器和加速度传感器测量设备相对于地磁北极的位置,还可以利用方向传感器确定当前设备相对于自身参照系的位置。

磁场传感器和方向传感器都返回值3个值(SensorEvent.values),而邻近传感器只返回1个值。

下面我们具体看一下他们的返回值:
方向传感器:

  • SensorEvent.values[0]:绕着Z轴旋转的角度。如果Y轴(正常拿手机的方向)正对着北方,该值是0,如果Y轴指向南方,改值是180,Y轴指向东方,该值是90,如果Y轴指向西方,该值是270。
  • SensorEvent.values[1]:绕着X轴旋转的度数。当从Z轴正方向朝向Y轴正方向,改值为正值。反之,为负值。该值在180至-180之间变动。
  • SensorEvent.values[2]:绕着Y轴旋转的度数。当从Z轴正方向朝向X轴正方向,改值为正值。反之,为负值。该值在180至-180之间变动。
    磁场传感器:
  • SensorEvent.values[0]:沿着X轴的磁力(μT,millitesla)
  • SensorEvent.values[1]:沿着Y轴的磁力(μT,millitesla)
  • SensorEvent.values[2]:沿着Y轴的磁力(μT,millitesla)
    邻近传感器:
    SensorEvent.values[0]:手机正面距离邻近物理的距离(CM)
    (1)临近传感器
    这里以临近传感器作为示例工程实现一下,其他传感器实现大同小异。
public class SensorActivity extends AppCompatActivity implements SensorEventListener {
  private TextView tvProximity;
  private SensorManager mSensorManager;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_motion_sensor);
    tvProximity = (TextView) findViewById(R.id.tv_proximity);
    //获取传感器SensorManager对象
    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
  }
  /**
   * 传感器精度变化时回调
   */
  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
  }
  /**
   * 传感器数据变化时回调
   */
  @Override
  public void onSensorChanged(SensorEvent event) {
    //判断传感器类别
    switch (event.sensor.getType()) {
      case Sensor.TYPE_PROXIMITY://临近传感器
        tvProximity.setText(String.valueOf(event.values[0]));
        break;
      default:
        break;
    }
  }
  /**
   * 界面获取焦点,按钮可以点击时回调
   */
  protected void onResume() {
    super.onResume();
    //注册临近传感器
    mSensorManager.registerListener(this,
        mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
        SensorManager.SENSOR_DELAY_UI);
  }
  /**
   * 暂停Activity,界面获取焦点,按钮可以点击时回调
   */
  @Override
  protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
  }
 
}

运行程序,我间断的挡住临近传感器,看一下效果图:
[图片上传失败...(image-d6c0ff-1567500246575)]
0.0是我挡住临近传感器时候的值,8.0是我将手移开时的值。

下面我们再来看一个比较叼的传感器,与自然息息相关。
6.环境传感器的组成及使用方法
Android提供了用于检测不同的外部环境的传感器。例如,可以检测周围空气的湿度、光线、空气的压强和温度,这些传感器都是基于硬件的传感器。除了光线传感器外,其他传感器在普通的Android设备中很少见。所以如果使用环境传感器,最好运行时对当前Android设备所支持的传感器进行检测。

(1)环境传感器的返回值

大多数动作传感器和位置传感器都返回多个值,而所有的环境传感器都只返回一个值:

传感器 Type值 返回值 单位
温度传感器 TYPE_AMBIENT_TEMPERATURE event.values[0] °C
压力传感器 TYPE_PRESSURE event.values[0] hPa
光线传感器 TYPE_LIGHT event.values[0] lx
湿度传感器 TYPE_RELATIVE_HUMIDITY event.values[0] RH(%)

注意:环境传感器返回的值很少受到杂音的干扰,而动作和位置传感器经常需要消除杂音的影响。例如,加速度传感器要消除重力对其回传值的影响。
(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;

环境传感器的使用方法与动作、位置传感器大同小异,在次不再赘述。
相信通过本篇文章的学习,大家都会有所提高。码字不易,喜欢点赞

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • Android传感器定义 Android 传感器相关术语微机电传感器(MEMS)MEMS 通常制作在规格很小的硅芯...
    Jannonx阅读 4,296评论 0 1
  • 作者ivm 参考文章:http://blog.csdn.net/wenzhi20102321/article/de...
    lovesosoi阅读 1,393评论 0 8
  • Android 传感器开发详解 传感器 传感器的分类 方向传感器 陀螺仪传感器 磁场传感器 重力传感器 线性加速度...
    CarlosLynn阅读 4,393评论 2 2
  • Android系统提供了对传感器的支持,如果手机设备的硬件提供了这些传感器,Android应用可以通过传感器来获取...
    trampcr阅读 4,264评论 3 12
  • 我的父亲是一名虔诚的佛教信徒,我也跟着玩金刚菩提有十多年了,因自己特别爱文玩,也想与更多的朋友一起分享盘玩经验。我...
    丿丶信仰灬傲世风阅读 410评论 0 1