android传感器高级编程_传感器程序编写

android传感器高级编程_传感器程序编写1.Android的三大类传感器Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器、环境(Environmental)传感器、位置(Position)传感器。(1)动作传感器这类传感器在三个轴(x、y、z)上测量加速度和旋转角度。包括如下几个传感器:加速(accelerometer)传感器、重力(gravity)传感器、陀螺仪(gyrosc

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

1.Android的三大类传感器

Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器、环境(Environmental)传感器、位置(Position)传感器。

(1)动作传感器

这类传感器在三个轴(x、y、z)上测量加速度和旋转角度。包括如下几个传感器:

加速(accelerometer)传感器、重力(gravity)传感器、陀螺仪(gyroscope)传感器、旋转向量(rotational vector )传感器

下面来看一下传感器世界的坐标系:

传感器世界的坐标系

是不是已经有点感觉了。

(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类型如下:

序号 传感器 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

注意:1-8是硬件传感器,9是软件传感器,其中方向传感器的数据来自重力和磁场传感器,10-12是硬件或软件传感器。

(3)SensorEvent类

系统使用该类创建传感器事件对象。该对象可以提供与传感器事件有关的信息。传感器事件对象包括的信息有原始的传感器回传数据、传感器类型、数据的精度以及触发事件的时间。

(4)SensorEventListener接口

该接口包含两个回调方法,当传感器的回传值或精度发生变化时,系统会调用这两个回调方法。

/** * 传感器精度变化时回调 */
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/** * 传感器数据变化时回调 */
@Override
public void onSensorChanged(SensorEvent event) {
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

到了这里,我们就可以进行传感器开发工作了。

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");
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

先运行一下看看效果:

获取传感器技术参数

貌似我的手机传感器还不少,哈哈。注意此处必须用实体机测试哦。

下来我们分别看一下动作传感器、环境传感器和位置传感器的组成及使用方法。

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);
    }

}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

我们将手机水平正面朝上放置于桌子上,看一下效果图:

加速度传感器

我们可以看到正值和负值,那什么情况是正值?什么情况是负值呢?

设备沿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);
    }

}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

运行程序,我间断的挡住临近传感器,看一下效果图:

临近传感器

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;
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

环境传感器的使用方法与动作、位置传感器大同小异,在次不再赘述。

相信通过本篇的学习,大家的开发水准都会有一定的提高,而大家的提高是我最欣慰的事情了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/187819.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java如何创建线程池_java线程池状态

    java如何创建线程池_java线程池状态分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net1、为什么要用线程池?线程池提供了一种限制和管理资源(包括执行一个任务)。每个线程池还维护一些基本统计信息,例如已完成任务的数量。这里借用《Java并发编程的艺术》,来说一下使用线程池的好处:降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。 提高线程的可管

  • 虚函数实现原理

    虚函数实现原理前言C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。关于虚函数的使用方法,我在这里不…

  • pycharm与python的关系_pycharm和python区别[通俗易懂]

    pycharm与python的关系_pycharm和python区别[通俗易懂]pycharm使用创建directory和Pythonpackage的区别pycharm能显示当前python文件下的函数和类的列表吗当然可以,调出Structure视图即可。①快捷键:Alt+7②鼠标移动到窗口左下角小方块,寻Structure”③点击View菜单,选ToolWindows,再寻Structure”pycharm教程(一)安装PyCharm是我…

  • ⁉️socket实现Ping命令打造⚡BOSS来了⚡摸鱼神器⭐干货巨多❤️建议收藏❤️

    ⁉️socket实现Ping命令打造⚡BOSS来了⚡摸鱼神器⭐干货巨多❤️建议收藏❤️大家好,我是????前面我写了篇水文《获取当前局域网下所有连接设备的ip地址和mac地址》,但是没有想到的是居然上了热榜,也是我个人第一篇上热榜的文章,阅读量瞬间飙升????。然而我的硬核技术文却几乎没有人看到。既然又很多人对这个话题感兴趣,那么我们就继续对相关原理深挖,最好能自己实现,理解透彻。首先我们回顾一下前文,在前文中我介绍了windows下获取ip地址和arp映射表的命令,通过分析最新arp映射表知道当前网段下在线或下线的设备⭐。文章使用的技术是通过python调用系统ping命令,实现ar

  • Android集成lrzsz[通俗易懂]

    Android集成lrzsz[通俗易懂]为啥要移植lrzsz本文中的lrzsz代码点击此处获取Hikey开发板有两类USB口,两组USB-TypeA母口作为Host,可以接键盘、鼠标。另一组mini-USB母口,作为devices,可以接到电脑上调试。但目前这两种接口无法同时使用,即通过键盘鼠标操作时不能使用ADB。虽然可以通过minicom或者putty之类的工具连接串口查看LOG、执行命令。但Android系统中缺少通过串口传

  • python批量生成测试用例_系统测试用例的编写依据

    python批量生成测试用例_系统测试用例的编写依据前言写用例之前,我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。har2case我们先来了解一下另一个项目har2case他的工作原理就是将当前主流的抓

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号