android开发笔记之高级主题—传感器的简单介绍

今天我们开始进入讲解android中的一些高级主题的用法,比如传感器、GPS、NFC、语音和人脸识别等。

这次来对传感器的一个简单介绍:

Android平台支持三大类的传感器:

    位移传感器 

这些传感器测量沿三个轴线测量加速度和旋转。这类包含加速度,重力传感器,陀螺仪,和矢量传感器。 

    环境传感器 

这些传感器测量各种环境参数,例如周围的空气温度和压力,光线,和湿度。这类包含气压,光线,和温度传感器。 

    位置传感器 

这些传感器测量设备的物理位置。这类包含方向和磁力传感器。

这些传感器的一些是基于硬件的,一些是基于软件的。基于硬件的传感器是内嵌到手机或者平板中的物理元件,它们通过直接测量指定的环境属性来得到它们的数据,例如加速度,磁场强度,或者角度变化。基于软件的传感器不是物理设备,尽管它们模仿基于硬件的传感器。基于软件的 传感器从一个或更多基于硬件的传感器获取它们的数据,并且有时候被称为虚拟传感器或者合成传感器。线性加速度传感器和重力传感器是基于软件传感器的例子。

很少Android设备有所有类型的传感器。例如,大部分手机和平板有一个加速计和磁场计,但是很少的设备拥有气压或者温度传感器。并且,一个设备可以拥有一个类型不止一个的传感器。例如,设备能有两个重力传感器,每个有不同的范围。

需要指出的是,传感器的坐标系统与屏幕坐标系统不同,传感器坐标系统的X轴沿屏幕向右;Y轴则沿屏幕向上,Z轴在垂直屏幕向上。

我们依次看看几种传感器:

1 加速度传感器

加速度传感器又叫G-sensor,返回x、y、z三轴的加速度数值。

该数值包含地心引力的影响,单位是m/s^2。

将手机平放在桌面上,x轴默认为0,y轴默认0,z轴默认9.81。

将手机朝下放在桌面上,z轴为-9.81。

将手机向左倾斜,x轴为正值。

将手机向右倾斜,x轴为负值。

将手机向上倾斜,y轴为负值。

将手机向下倾斜,y轴为正值。

2 磁力传感器

磁力传感器简称为M-sensor,返回x、y、z三轴的环境磁场数据。

该数值的单位是微特斯拉(micro-Tesla),用uT表示。

单位也可以是高斯(Gauss),1Tesla=10000Gauss。

硬件上一般没有独立的磁力传感器,磁力数据由电子罗盘传感器提供(E-compass)。

电子罗盘传感器同时提供下文的方向传感器数据。

3 方向传感器

方向传感器简称为O-sensor,返回三轴的角度数据,方向数据的单位是角度。

为了得到精确的角度数据,E-compass需要获取G-sensor的数据,

经过计算生产O-sensor数据,否则只能获取水平方向的角度。

方向传感器提供三个数据,分别为azimuth、pitch和roll。

azimuth:方位,以z轴为轴,返回水平时磁北极和Y轴的夹角,范围为0°至360°。

0°=北,90°=东,180°=南,270°=西。

pitch:x轴和水平面的夹角,范围为-180°至180°。

当z轴向y轴转动时,角度为正值。

roll:y轴和水平面的夹角,由于历史原因,范围为-90°至90°。

当x轴向z轴移动时,角度为正值。

4 陀螺仪传感器

陀螺仪传感器叫做Gyro-sensor,返回x、y、z三轴的角加速度数据。

角加速度的单位是radians/second。

根据Nexus S手机实测:

水平逆时针旋转,Z轴为正。

水平逆时针旋转,z轴为负。

向左旋转,y轴为负。

向右旋转,y轴为正。

向上旋转,x轴为负。

向下旋转,x轴为正。

5 光线感应传感器

光线感应传感器检测实时的光线强度,光强单位是lux,其物理意义是照射到单位面积上的光通量。

光线感应传感器主要用于Android系统的LCD自动亮度功能。

可以根据采样到的光强数值实时调整LCD的亮度。

6 压力传感器

压力传感器返回当前的压强,单位是百帕斯卡hectopascal(hPa)。

7 温度传感器

温度传感器返回当前的温度。

8 距离传感器

距离传感器检测物体与手机的距离,单位是厘米。

一些距离传感器只能返回远和近两个状态,

因此,距离传感器将最大距离返回远状态,小于最大距离返回近状态。

距离传感器可用于接听电话时自动关闭LCD屏幕以节省电量。

一些芯片集成了距离传感器和光线传感器两者功能。

下面三个传感器做个比较:

重力传感器

重力传感器简称GV-sensor,输出重力数据。

在地球上,重力数值为9.8,单位是m/s^2。

坐标系统与加速度传感器相同。

当设备复位时,重力传感器的输出与加速度传感器相同。

线性加速度传感器

线性加速度传感器简称LA-sensor。

线性加速度传感器是加速度传感器减去重力影响获取的数据。

单位是m/s^2,坐标系统与加速度传感器相同。

加速度传感器、重力传感器和线性加速度传感器的计算公式如下:

加速度 = 重力 + 线性加速度

旋转矢量传感器

旋转矢量传感器简称RV-sensor。

旋转矢量代表设备的方向,是一个将坐标轴和角度混合计算得到的数据。

RV-sensor输出三个数据:

x*sin(theta/2)

y*sin(theta/2)

z*sin(theta/2)

sin(theta/2)是RV的数量级。

RV的方向与轴旋转的方向相同。

RV的三个数值,与cos(theta/2)组成一个四元组。

RV的数据没有单位,使用的坐标系与加速度相同。

传感器框架:

你能访问这些传感器,是通过使用Android传感器框架获取原始数据。Android传感器框架式android.hardware包的一部分,包含下面的类和接口:

SensorManager

你能使用这个类来创建一个传感器服务的实例。这个类提供了各种方法类访问和列举传感器,注册和注销传感器事件监听,并获取相应的信息。这个类也提供了几个传感器的常量,用户报告传感器的精确度,设置数据获取速率,和校准传感器。

Sensor

你能使用这个类来创建一个指定传感器的实例。这个类提供了各种方法让你确定传感器的功能。

SensorEvent

它提供了关于传感器事件的信息。一个传感器事件包含以下信息:原始传感器数据,这类传感器产生的事件,数据的准确性,和事件的时间戳。

SensorEventListener

你能使用这个接口来创建两个回调方法,当传感器的值改变或者当传感器的精度改变的时候,它接受通知(传感器事件)。

  • 传感器的值改变

    在这种情况下系统调用onSensorChanged()方法,向你提供了一个SensorEvent对象,一个SensorEvent对象包含关于新的传感器数据的信息,包括:数据的精度,传感器产生的数据,数据产生的时间戳,和传感器记录的新的数据。

  • 传感器精度的变化

    在 这种情况下系统调用onAccuracyChanged()方法,向你提供改变了新的传感器精度的Sensor对象引用。精度通过四个状态常量代 表:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGH, 或者SENSOR_STATUS_UNRELIABLE。

使用传感器的步骤如下:

①调用Context的getSystemService(Context.SENSOR_SERVICE)方法获取SensorManager对象。

②调用SensorManager的getDefaultSensor(int type)方法来获取指定类型的传感器。

从传感器管理器中获取其中某个或者某些传感器的方法有如下三种:

第一种:获取某种传感器的默认传感器

   Sensor defaultGyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

第二种:获取某种传感器的列表

   List<Sensor> pressureSensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);

第三种:获取所有传感器的列表,我们这个例子就用的第三种

   List<Sensor> allSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

③一般在Activity的onResume()方法中调用SensorManager的registerListener()为指定传感器注册监听器即可。程序可以通过实现监听器即可获取传感器传回来的数据。

SersorManager提供的注册传感器的方法为registerListener(SensorListener listener, Sensor sensor, int rate)该方法中三个参数说明如下:

listener:监听传感器事件的监听器

sensor:传感器对象

rate:指定获取传感器数据的频率

rate可以获取传感器数据的频率,支持如下几个频率值:

    SENSOR_DELAY_FASTEST:最快,延迟最小。

    SENSOR_DELAY_GAME:适合游戏的频率。

    SENSOR_DELAY_NORMAL:正常频率

    SENSOR_DELAY_UI:适合普通用户界面的频率。

那就来举个例子来测试下:

这个例子就是显示下手机上支持的传感器及传感器的一些信息并测试几个常用传感器

效果:

核心代码:

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.fenxichuanganqi.MainActivity" >

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="方向传感器:"
        android:textColor="#ff0000" />

    <TextView
        android:id="@+id/tv_direction"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="线性传感器:"
        android:textColor="#ff0000" />

    <TextView
        android:id="@+id/tv_xianxing"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加速度传感器:"
        android:textColor="#ff0000" />

    <TextView
        android:id="@+id/tv_jiasudu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="光强传感器:"
        android:textColor="#ff0000" />

    <TextView
        android:id="@+id/tv_guangqiang"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="距离传感器:"
        android:textColor="#ff0000" />

    <TextView
        android:id="@+id/tv_juli"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity implements SensorEventListener{

    private TextView tv;
    private TextView tv_direction;
    private TextView tv_xianxing;
    private TextView tv_jiasudu;
    private TextView tv_guangqiang;
    private TextView tv_juli;
    private SensorManager sensorManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.获取SensorManager服务
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        tv = (TextView) findViewById(R.id.tv);
        tv_direction = (TextView) findViewById(R.id.tv_direction);
        tv_xianxing = (TextView) findViewById(R.id.tv_xianxing);
        tv_jiasudu = (TextView) findViewById(R.id.tv_jiasudu);
        tv_guangqiang = (TextView) findViewById(R.id.tv_guangqiang);
        tv_juli = (TextView) findViewById(R.id.tv_juli);
        //获取手机上支持的传感器
        List<Sensor> list = sensorManager.getSensorList(Sensor.TYPE_ALL);
        tv.append("手机上有" + list.size() + "个传感器" + "\n");
        for (Sensor sensor : list) {
            String msg = "名字:" + sensor.getName() + ",版本:" + sensor.getVersion()
                    +",供应商:" + sensor.getVendor() + ",类型:" + sensor.getType();
            tv.append(msg + "\n");
        }
    }
    @Override
    protected void onResume() {
        //23.获得相应传感器并注册监听器
        //第三个参数表示精度
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                sensorManager.SENSOR_DELAY_UI);
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
                sensorManager.SENSOR_DELAY_UI);
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                sensorManager.SENSOR_DELAY_UI);
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
                sensorManager.SENSOR_DELAY_UI);
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
                sensorManager.SENSOR_DELAY_UI);
        super.onResume();
    }
    @Override
    protected void onStop() {
        //4.解除绑定
        sensorManager.unregisterListener(this);
        super.onStop();
    }
    @Override
    public void onSensorChanged(SensorEvent event) {
        //传感器数据变化,在该方法中我们可以获取传感器变化的值
        switch (event.sensor.getType()) {
        case Sensor.TYPE_ORIENTATION:
            float z = event.values[0];
            float x = event.values[1];
            float y = event.values[2];
            tv_direction.setText("z轴的方向:" + z + "\n"
                    + "x轴的方向:" + x + "\n"
                    + "y轴的方向:" + y + "\n");
            break;
        case Sensor.TYPE_LINEAR_ACCELERATION:
            float x1 = event.values[0];
            float y1 = event.values[1];
            float z1 = event.values[2];
            tv_xianxing.setText("x轴的加速度:" + x1 + "\n"
                    + "y轴的加速度:" + y1 + "\n"
                    + "z轴的加速度:" + z1 + "\n");
            break;
        case Sensor.TYPE_ACCELEROMETER:
            float x2 = event.values[0];
            float y2 = event.values[1];
            float z2 = event.values[2];
            tv_jiasudu.setText("x轴的加速度:" + x2 + "\n"
                    + "y轴的加速度:" + y2 + "\n"
                    + "z轴的加速度:" + z2 + "\n");
            break;
        case Sensor.TYPE_LIGHT:
            float light = event.values[0];
            tv_guangqiang.setText("光强:" + light);
            break;
        case Sensor.TYPE_PROXIMITY:
            float distanse = event.values[0];
            tv_juli.setText("距离传感器:" + distanse);
            break;
        default:
            break;
        }
    }
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //传感器精度的变化
    }
}

这个传感器的介绍就这些,大家应该都看得懂。赶紧拿出自己的手机来试试吧。

访问和使用传感器的总结:

①注销传感器监听器

当你完成使用传感器的事情或者当传感器activity pause的时候,确保注销传感器监听器。如果一个传感器的监听器被注册并且它的activity被pause,这个传感器将继续获取数据并且使用电池资源,除非你注销这个传感器。

mSensorManager.unregisterListener(this);

②不要在模拟器上测试你的代码

你目前不能再模拟器上测试你的传感器代码,因为模拟器不能模拟传感器。你必须在一个物理设备上测试你的传感器代码。

③不要阻塞onSensorChanged()方法

传感器数据可以高速的变化,这意味着系统可能经常调用onSensorChanged(SensorEvent)方法。作为一项最佳的实践,你应该竟可能少 的在onSensorChanged(SensorEvent)方法中做事情,所以你没有阻塞它。如果你的应用程序要求你做任何数据过滤或者减少传感器数 据,你应该在onSensorChanged(SensorEvent)方法外执行这个工作。

④避免使用过时的方法或者传感器类型

几个方法和常量已经被弃用。尤其,TYPE_ORIENTATION传感器类型已经被弃用。为了获取方向数据你应该使用getOrientation()方 法替代。同样,TYPE_TEMPERATURE传感器类型已经被弃用。你应该在运行Andorid4.0的设备上使用TYPE_AMBIENT_TEMPERATURE传感器类型替代。

⑤在你使用它们之前验证传感器

在你尝试从它获取数据之前,总是验证在一个传感器在设备上是否存在。不要因为它是一个常用的传感器而简单假设传感器存在。设备厂商没有被要求在它们的设备上提供任何指定的传感器。

⑥仔细选择传感器延迟

当你使用registerListener()方法中注册一个传感器的时候,确保你选择一个适合你的应用程序或者用例的分发率。传感器能非常高速提供数据。允许系统发送额外的你不需要浪费系统资源并使用电池的数据。
时间: 2024-12-22 19:22:28

android开发笔记之高级主题—传感器的简单介绍的相关文章

【转】Android开发笔记(序)写在前面的目录

原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入门上:其次是想拾缺补漏,写写虽然小众却又用得着的东西:另外就是想以实用为主,不求大而全,但求小而精:还有就是有的知识点是java的,只是Android开发也会经常遇上,所以蛮记下来.个人的经

Android开发笔记(一百一十六)网络学习资源

知名网站 本系列的开发笔记,对Android开发来说只是沧海一瓢,还有更多的技术等待我们去汲取.下面列出几个常用的开发网站,供初学者上路: 首先当然是国内首屈一指的技术网站csdn啦,csdn提供了众多频道,包括博客.论坛.下载.问答等等,其中博客专栏提供了最新的技术文章,值得推荐.csdn博客专栏的地址是 http://blog.csdn.net/column.html 下面是csdn博客专栏的网页截图: 其次是国外有名的开源网站GitHub,这里有众多的开源项目源码,是开发者分享代码的乐园.

Android开发笔记(一百零七)统计分析SDK

APP统计分析 用户画像 对程序员来说,用户画像就是用户的属性和行为:通俗地说,用户画像是包括了个人信息.兴趣爱好.日常行为等血肉丰满的客户实体.用户画像是精准营销的产物,企业通过收集用户的行为,然后分析出用户的特征与偏好,进而挖掘潜在的商业价值,实现企业效益的最大化. 用户画像的一个具体应用是电商app的"猜你喜欢"栏目,电商平台通过对用户购买过的商品进行统计,可以分析用户日常生活用的是什么物品:电商平台还可以对用户的搜索行为.浏览行为进行统计,从中分析用户感兴趣的商品,或者说考虑购

Android开发笔记(一百一十七)app省电方略

电源管理PowerManager PowerManager是Android的电源管理类,用于管理电源操作如睡眠.唤醒.重启以及调节屏幕亮度等等. PowerManager的对象从系统服务POWER_SERVICE中获取,它的主要方法如下: goToSleep : 睡眠,即锁屏. wakeUp : 唤醒,即解锁. reboot : 重启. 另有下列几个隐藏的方法: getMinimumScreenBrightnessSetting : 获取屏幕亮度的最小值. getMaximumScreenBri

Android开发笔记(九十八)往图片添加部件

添加圆角 添加圆角的功能,要用到Canvas类的drawRoundRect方法,即把画布裁剪成指定的圆角矩形. 下面是给图片添加圆角的效果截图: 下面是给图片添加圆角的代码片段: public static Bitmap getRoundImage(Bitmap bitmap, int roundPixels) { //创建一个和原始图片一样大小位图 Bitmap roundConcerImage = Bitmap.createBitmap(bitmap.getWidth(), bitmap.g

Android开发笔记(一百零三)地图与定位SDK

集成地图SDK 国内常用的地图SDK就是百度和高德了,二者的用法大同小异,可按照官网上的开发指南一步步来.下面是我在集成地图SDK时遇到的问题说明: 1.点击基本地图功能选项,不能打开地图,弹出"key验证出错!请在AndroidManifest.xml文件中检查key设置的"的红色字提示.查看日志提示"galaxy lib host missing meta-data,make sure you know the right way to integrate galaxy&

[APP] Android 开发笔记 003

接上节 [APP] Android 开发笔记 002 5. 使用ant release 打包 1)制作 密钥文件 release.keystore (*.keystore) keytool -genkey -v -keystore "release.keystore" -alias "release" -keyalg "RSA" -validity "10000" 这里需要注意的是: -keystore "relea

张高兴的 Windows 10 IoT 开发笔记:BH1750FVI 光照度传感器

原文:张高兴的 Windows 10 IoT 开发笔记:BH1750FVI 光照度传感器 BH1750FVI 是一款 IIC 接口的数字型光强度传感器集成电路.下面介绍一下其在 Windows 10 IoT Core 环境下的用法. 项目运行在 Raspberry Pi 2/3 上,使用 C# 进行编码. 1. 准备 包含 BH1750FVI 的传感器,这里选择的是淘宝上最多的 GY-30:Raspberry Pi 2/3 一块,环境为 Windows 10 IoT Core:公母头杜邦线 4-

张高兴的 Windows 10 IoT 开发笔记:DHT11 温湿度传感器

原文:张高兴的 Windows 10 IoT 开发笔记:DHT11 温湿度传感器 GitHub : https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/DHT11Demo