当前位置: 首页 > news >正文

【Android入门到项目实战-- 9.1】—— 传感器的使用教程

目录

传感器的定义

三大类型传感器

1、运动传感器

2、环境传感器

3、位置传感器

传感器开发框架

1、SensorManager

2、Sensor

3、SensorEvent

4、SensorEventListener

一、使用传感器开发步骤

1、获取传感器信息

1)、获取传感器管理器

2)、获取设备的传感器对象列表

3)、迭代获取Sensor对象,调用对应方法获取相关信息

2、获取传感器传回数据

1)获得传感器管理器

2)调用特定方法获得需要的传感器

3)实现SensorEventListener接口,重写onSensorChanged和onAccuracyChanged方法

4)SensorManager对象调用registerListener注册监听器

5)监听器的取消注册

二、获取传感器信息的实例

三、获取传感器传回数据的实例

原理


        传感器的应用如微信的摇一摇功能、NFC、手机自带的指南针等等。下面将学习Android传感器的使用。

传感器的定义

        一种物理设备或者生物器官,能够探测、感受外界的信号,物理条件(如光,热, 湿度)或化学组成(如烟雾),并将探知的信息传递给其他的设备或者器官。

三大类型传感器

1、运动传感器

        –运动传感器测量加速力和旋转力,它们包括加速度计,重力传感器,陀螺仪和旋转矢量传感器。

2、环境传感器

        –环境传感器测量各种周围环境情况,如环境温度、气压、光强、湿度等。包括气压计,光度计和温度计。

3、位置传感器

        –位置传感器测量设备的物理位置信息,包括方向传感器和磁力计。

传感器开发框架

1、SensorManager

        –可以使用此类创建传感器服务的实例。这个类提供了多种方法来访问和列出传感器,注册和注销传感器事件监听器,并获取方向信息。该类还提供了几个传感器常量,用于报告传感器的精度,设置数据采集速率和校准传感器。

2、Sensor

        –可以使用此类创建特定传感器的实例。这个类提供了各种方法,让你确定一个传感器的能力。

3、SensorEvent

        –系统使用此类创建传感器事件对象,该对象提供有关传感器事件的信息。传感器事件对象包括以下信息:原始传感器数据,生成事件的传感器类型,数据的准确性以及事件的时间戳。

4、SensorEventListener

        –可以使用此界面创建两种回传方法,当传感器值更改或传感器准确度发生变化时,会接收通知(传感器事件)。

一、使用传感器开发步骤

1、获取传感器信息

        传感器的开发首先需要获取传感器的一些信息,获取信息需要以下步骤:

1)、获取传感器管理器

        Android提供了一个sensorManager管理器,通过这个类可以获取到都有哪些传感器,获取sensorManager对象代码如下:

SensorManager sm = (SensorManager)getSystemService(SENSOR_SERVICE); 

2)、获取设备的传感器对象列表

        通过sensorManager管理器的getSensorList()方法,可以获取传感器对象列表,具体代码如下:

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

3)、迭代获取Sensor对象,调用对应方法获取相关信息

for(Sensor s:allSensors){sensor.getName();   //获得传感器名称sensor.getType();     //获得传感器种类sensor.getVendor();    //获得传感器供应商sensor.getVersion();    //获得传感器版本sensor.getResolution();  //获得精度值sensor.getMaximumRange(); //获得最大范围sensor.getPower();        //传感器使用时的耗电量 
}

2、获取传感器传回数据

1)获得传感器管理器

SensorManager sm = (SensorManager)getSystemService(SENSOR_SERVICE);

2)调用特定方法获得需要的传感器

        调用SensorManager 对象的getDefaultSensor方法,获取指定类型的传感器,例如这里使用光线传感器,具体代码:

Sensor mSensorOrientation = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);

3)实现SensorEventListener接口,重写onSensorChanged和onAccuracyChanged方法

①:onSensorChanged(SensorEvent event);该方法在传感器的值发生改变的时候调用,其参数是一个SensorEvent 对象,通过该对象的values属性可以获取传感器的值,该值是一个数组,该变量最多有三个元素,而且传感器不同,对应元素代表的含义也不同
②:onAccuracyChanged(Sensor sensor , int accuracy);当传感器的进度发生改变时会回调,
参数说明:
sensor:传感器对象
accuracy:表示传感器新的精度

@Override
public void onSensorChanged(SensorEvent event) {final float[] _Data = event.values;this.mService.onSensorChanged(_Data[0],_Data[1],_Data[2]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

4)SensorManager对象调用registerListener注册监听器

        为传感器注册监听事件,通过调用sensorManager对象的registerListener()方法来注册监听事件。

        第一个参数是上下文对象,第二个是传感器对象,第三个是传感器的延时时间的精密程 度,越精密越耗电。

        

  • SENSOR_DELAY_FASTEST——延时:0ms
  • SENSOR_DELAY_GAME——延时:20ms
  • SENSOR_DELAY_UI——延时:60ms
  • SENSOR_DELAY_NORMAL——延时:200ms

具体代码如下:

sm.registerListener(mContext, mSensorOrientation, android.hardware.SensorManager.SENSOR_DELAY_UI);

5)监听器的取消注册

sm. unregisterListener(this);

二、获取传感器信息的实例

        先将前面第一个步骤:获取传感器信息,实例演示一下如何使用。

新建项目SensorDemo1。

修改activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/txt_show"android:layout_width="match_parent"android:layout_height="match_parent" /></ScrollView></androidx.constraintlayout.widget.ConstraintLayout>

修改MainActivity代码如下:

public class MainActivity extends AppCompatActivity {private TextView txt_show;private SensorManager sm;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);txt_show = (TextView) findViewById(R.id.txt_show);List<Sensor> allSensors = sm.getSensorList(Sensor.TYPE_ALL);StringBuilder sb = new StringBuilder();sb.append("此手机有" + allSensors.size() + "个传感器,分别有:\n\n");for(Sensor s:allSensors){switch (s.getType()){case Sensor.TYPE_ACCELEROMETER:sb.append(s.getType() + " 加速度传感器(Accelerometer sensor)" + "\n");break;case Sensor.TYPE_GYROSCOPE:sb.append(s.getType() + " 陀螺仪传感器(Gyroscope sensor)" + "\n");break;case Sensor.TYPE_LIGHT:sb.append(s.getType() + " 光线传感器(Light sensor)" + "\n");break;case Sensor.TYPE_MAGNETIC_FIELD:sb.append(s.getType() + " 磁场传感器(Magnetic field sensor)" + "\n");break;case Sensor.TYPE_ORIENTATION:sb.append(s.getType() + " 方向传感器(Orientation sensor)" + "\n");break;case Sensor.TYPE_PRESSURE:sb.append(s.getType() + " 气压传感器(Pressure sensor)" + "\n");break;case Sensor.TYPE_PROXIMITY:sb.append(s.getType() + " 距离传感器(Proximity sensor)" + "\n");break;case Sensor.TYPE_TEMPERATURE:sb.append(s.getType() + " 温度传感器(Temperature sensor)" + "\n");break;default:sb.append(s.getType() + " 其他传感器" + "\n");break;}sb.append("设备名称:" + s.getName() + "\n 设备版本:" + s.getVersion() + "\n 供应商:"+ s.getVendor() + "\n\n");}txt_show.setText(sb.toString());}
}

效果如下:

 

三、获取传感器传回数据的实例

           实现前面第二个步骤:获取传感器传回数据,实例演示一下如何使用。下面实现采集方向传感器数据。

原理

 

X 轴的方向 :沿着屏幕水平方向从左到右,如果手机如果不是是正方形的话,较短的边需要水平 放置,较长的边需要垂直放置。值域 [-180, 180]
Y 轴的方向 :从屏幕的左下角开始沿着屏幕的的垂直方向指向屏幕的顶端。值域 [-90, 90]
Z 轴的方向 :当水平放置时,指向天空的方向。值域 [0, 360]

 

新建项目SensorDemo2。

修改activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="5dp"><TextViewandroid:id="@+id/tv_value1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="方位角"android:textSize="18sp"android:textStyle="bold" /><TextViewandroid:id="@+id/tv_value2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="倾斜角"android:textSize="18sp"android:textStyle="bold" /><TextViewandroid:id="@+id/tv_value3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="滚动角"android:textSize="18sp"android:textStyle="bold" /></LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>

修改MainActivity代码如下:

        

SENSOR_DELAY_FASTEST最灵敏

SENSOR_DELAY_GAME 游戏的时候,不过一般用这个就够了

SENSOR_DELAY_NORMAL 比较慢。

SENSOR_DELAY_UI 最慢的

public class MainActivity extends AppCompatActivity implements SensorEventListener {private TextView tv_value1;private TextView tv_value2;private TextView tv_value3;private SensorManager sManager;private Sensor mSensorOrientation;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sManager = (SensorManager) getSystemService(SENSOR_SERVICE);mSensorOrientation = sManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);sManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_UI);bindViews();}private void bindViews() {tv_value1 = (TextView) findViewById(R.id.tv_value1);tv_value2 = (TextView) findViewById(R.id.tv_value2);tv_value3 = (TextView) findViewById(R.id.tv_value3);}@Overridepublic void onSensorChanged(SensorEvent event) {tv_value1.setText("方位角(沿Z轴):" + (float) (Math.round(event.values[0] * 100)) / 100);tv_value2.setText("倾斜角(沿X轴):" + (float) (Math.round(event.values[1] * 100)) / 100);tv_value3.setText("滚动角(沿Y轴):" + (float) (Math.round(event.values[2] * 100)) / 100);}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}@Overrideprotected void onDestroy() {super.onDestroy();sManager.unregisterListener(this);}
}

效果如下:

 

下篇文章将通过靠近屏幕黑屏和计步器两个案例实践一下传感器的应用。

相关文章:

【Android入门到项目实战-- 9.1】—— 传感器的使用教程

目录 传感器的定义 三大类型传感器 1、运动传感器 2、环境传感器 3、位置传感器 传感器开发框架 1、SensorManager 2、Sensor 3、SensorEvent 4、SensorEventListener 一、使用传感器开发步骤 1、获取传感器信息 1)、获取传感器管理器 2)、获取设备的传感器对象列…...

yolov8 浅记

目录 Pre: 1. YOLOv8 概述 2. 模型结构设计 3. Loss 计算 4.训练数据增强 5. 训练策略 6、部署推理 End Pre: yolo系列发布时间&#xff1a; 先贴一下yolo各系列的发布时间&#xff08;说出来很丢人&#xff0c;我以为 yolox是 最新的&#xff09;&#xff1a; yoloX 2…...

前端009_类别模块_修改功能

第九章 1、需求分析2、Mock添加查询数据3、Mock修改数据4、Api调用回显数据5、提交修改后的数据6、效果1、需求分析 需求分析 当点击 编辑 按钮后,弹出编辑窗口,并查询出分类相关信息进行渲染。修改后点击 确定 提交修改后的数据。 2、Mock添加查询数据 请求URL: /article/…...

2022级吉林大学面向对象第一次上机测试

【注&#xff1a;解答全部为本人所写&#xff0c;仅供同学们学习时参考使用&#xff0c;请勿照搬抄袭&#xff01;】 1、 1&#xff09;略 2&#xff09;如果main,f1,g1,g2或更多的函数之间有更为复杂的调用关系&#xff0c;头文件一般按怎样的规律写呢&#xff1f; 一般情况下…...

计算机体系结构总结:内存一致性模型 Memory consistency Model

存储一致性是为了保证多线程背景下的访存顺序&#xff0c;多线程的语句是可以交错执行&#xff0c;使得顺序不同产生不同的执行结果。 下面P2的输出结果可能是什么&#xff1f; P1, P2两个线程的语句是可以交叉执行的&#xff0c;比如1a, 2a, 2b, 1b&#xff1b;一个线程内的语…...

高速列车运行控制系统(CTCS)介绍

1、CTCS功能 安全防护 在任何情况下防止列车无行车许可运行防止列车超速运行防止列车超过进路允许速度防止列车超过线路结构规定的速度防止列车超过机车车辆构造速度防止列车超过临时限速及紧急限速防止列车超过铁路有关运行设备的限速防止列车溜逸 人机界面 以字符、数字及…...

C#“System.Threading.ThreadStateException”类型的未经处理的异常

备忘 最近做一个功能&#xff0c;从主界面进入另一个界面时&#xff0c;数据量较大&#xff0c;处理信息较多&#xff0c;程序宕机。而且点击程序还会提示程序无响应。不得已用另一个线程显示界面。但在界面中使用控件时&#xff0c;报错&#xff1a;“System.Threading.Thread…...

为什么要交叉编译?

一、什么是交叉编译、为什么要交叉编译 1、什么是交叉编译&#xff1f; 交叉编译&#xff1a;是在一个平台上生成另一个平台上的可执行代码。比如我们在 x86 平台上&#xff0c;编写程序并编译成能运行在 ARM 平台的程序&#xff0c;编译得到的程序在 x86 平台上是不能运行的…...

java版本电子招标采购系统源码—企业战略布局下的采购

​ 智慧寻源 多策略、多场景寻源&#xff0c;多种看板让寻源过程全程可监控&#xff0c;根据不同采购场景&#xff0c;采取不同寻源策略&#xff0c; 实现采购寻源线上化管控&#xff1b;同时支持公域和私域寻源。 询价比价 全程线上询比价&#xff0c;信息公开透明&#xff0…...

【MATLAB数据处理实用案例详解(17)】——利用概念神经网络实现柴油机故障诊断

目录 一、问题描述二、利用概念神经网络实现柴油机故障诊断原理三、算法步骤3.1 定义样本3.2 样本归一化3.3 创建网络模型3.4 测试3.5 显示结果 四、运行结果五、完整代码 一、问题描述 柴油机的结构较为复杂&#xff0c;工作状况非常恶劣&#xff0c;因此发生故障的可能性较大…...

神奇字符串、密钥格式化----2023/5/6

神奇字符串----2023/5/6 神奇字符串 s 仅由 ‘1’ 和 ‘2’ 组成&#xff0c;并需要遵守下面的规则&#xff1a; 神奇字符串 s 的神奇之处在于&#xff0c;串联字符串中 ‘1’ 和 ‘2’ 的连续出现次数可以生成该字符串。 s 的前几个元素是 s “1221121221221121122……” 。…...

STM32F4_十进制和BCD码的转换

目录 前言 1. BCD码 2. BCD码和十进制转换的算法 前言 最近在学习STM32单片机&#xff08;不仅仅是32&#xff09;的RTC实时时钟系统的过程中&#xff0c;需要配置时钟的时间、日期&#xff1b;这些都需要实现BCD码和十进制之间进行转换。这里和大家一起学习BCD码和十进制之…...

random — 伪随机数生成器(史上总结最全)

目的&#xff1a;实现几种类型的伪随机数生成器。 random 模块基于 Mersenne Twister 算法提供了一个快速的伪随机数生成器。Mersenne Twister 最初开发用于为蒙特卡洛模拟器生成输入&#xff0c;可生成具有分布均匀&#xff0c;大周期的数字&#xff0c;使其可以广泛用于各种…...

基于VBA实现成绩排序的最佳方法-解放老师的双手

作为一名老师&#xff0c;每到期末就要面对一件让人头疼的事情——成绩表统计。 首先&#xff0c;要收集每个学生的考试成绩。这需要花费大量的时间和精力&#xff0c;因为每个学生都有多门科目的成绩需要统计。 其次&#xff0c;要将每个学生的成绩录入到电子表格中。这看起来…...

OCAF如何实现引用关系和拓扑关系

在 OpenCASCADE 中,TDF_Label 是用来保存对象及其属性的基本单元。TDF_Label 可以通过添加不同类型的属性来保存不同的数据类型。属性是继承自 TDF_Attribute 类的对象,每个属性都有一个唯一的标识符(GUID)来识别其类型。TDF_Label是OpenCASCADE中用来管理数据的标签类,它…...

自动创建设备节点

在成功加载驱动模块之后&#xff0c;还需要使用 mknod命令创建设备节点&#xff0c;才能在/dev目录下创建对应的设备文件。自动创建设备节点的功能需要依赖 mdev 设备管理机制&#xff0c;在使用 buildroot 构建 rootfs 的时候&#xff0c;会默认构建 mdev 的功能&#xff0c;m…...

JavaWeb ( 六 ) JSP

2.4.JSP JSP (Java Server Pages) : 一种在服务器端生成动态页面的技术&#xff0c;本质上就是Servlet。将HTML代码嵌入到Java代码中, 通过Java逻辑控制HTML代码的结构从而生成页面。在MVC中通常担任视图层&#xff08;view&#xff09;&#xff0c;负责信息的展示与收集。 2…...

2023世界超高清视频产业发展大会博冠8K明星展品介绍

2023世界超高清视频产业发展大会博冠8K明星展品介绍&#xff1a; 一、博冠8K全画幅摄像机B1 这是一款面向广电应用的机型&#xff0c;可适配外场ENG制作轻量化需求&#xff0c;应用于8K单边机位、新闻、专题的拍摄工作&#xff0c;也可应用于体育转播、文艺节目等特殊机位及各…...

Map接口以及Collections工具类

文章目录 1.Map接口概述1.1 Map的实现类的结构1.2 Map中存储的key-value结构的理解1.3 HashMap的底层实现原理(以JDK7为例)1.4 Map接口的常用方法1.5 TreeMap1.6 Map实现类之五: Properties 1.Collections工具类1.1方法1.1.1 排序操作(均为static方法)1.1.2 查找、替换 1.Map接…...

SOA协议DDS和Some/IP对比

SOME/IP 和 DDS 均已被纳入AUTOSAR AP的平台标准中。 SOME/IP 和 DDS是在不同的应用场景和不同的需求下诞生的技术&#xff0c;所以它们之间注定有很大的区别。 SOME/IP SOME/IP的全称为&#xff1a;Scalable service-Oriented MiddlewarE over IP&#xff0c;是一种面向服务…...

Z-Image-Turbo_Sugar脸部Lora效果增强:ControlNet+Lora联合调控Sugar脸部结构

Z-Image-Turbo_Sugar脸部Lora效果增强&#xff1a;ControlNetLora联合调控Sugar脸部结构 想生成那种又纯又欲、甜度爆表的Sugar风格脸部图片吗&#xff1f;是不是经常遇到模型生成的脸型不够精致、五官比例失调&#xff0c;或者风格不够统一的问题&#xff1f;今天&#xff0c…...

卷积神经网络原理与Baichuan-M2-32B医疗图像识别实战

卷积神经网络原理与Baichuan-M2-32B医疗图像识别实战 1. 引言 医疗图像识别一直是人工智能领域的重要应用方向。传统的图像识别方法往往需要大量的人工特征工程&#xff0c;而卷积神经网络的出现彻底改变了这一局面。今天&#xff0c;我们将深入探讨卷积神经网络的核心原理&a…...

DASD-4B-Thinking效果对比:在HumanEval代码生成任务中超越Qwen2.5-7B

DASD-4B-Thinking效果对比&#xff1a;在HumanEval代码生成任务中超越Qwen2.5-7B 1. 为什么这个40亿参数模型值得关注&#xff1f; 你可能已经用过不少大模型&#xff0c;但有没有遇到过这种情况&#xff1a;写一段Python函数时&#xff0c;模型直接给出答案&#xff0c;却跳…...

AI净界-RMBG-1.4入门指南:理解Alpha通道、PNG透明度与导出规范

AI净界-RMBG-1.4入门指南&#xff1a;理解Alpha通道、PNG透明度与导出规范 你是不是也遇到过这样的烦恼&#xff1f;拍了一张不错的照片&#xff0c;想换个背景发朋友圈&#xff0c;或者做电商需要把商品图抠出来&#xff0c;结果发现边缘抠得跟狗啃的一样&#xff0c;头发丝和…...

避坑指南:OpenClaw连接Qwen3-32B镜像的5大常见错误

避坑指南&#xff1a;OpenClaw连接Qwen3-32B镜像的5大常见错误 1. 为什么连接Qwen3-32B镜像容易踩坑&#xff1f; 上周我在本地尝试用OpenClaw对接Qwen3-32B镜像时&#xff0c;经历了从满怀期待到怀疑人生的全过程。本以为有了官方镜像就能一键连通&#xff0c;结果从环境配置…...

LeetCode 98. Validate Binary Search Tree 题解

LeetCode 98. Validate Binary Search Tree 题解 题目描述 给你一个二叉树的根节点 root&#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子…...

从零构建CPWC超声成像仿真:Field II实战与模块化工作流解析

1. CPWC超声成像仿真入门指南 第一次接触CPWC超声成像仿真时&#xff0c;我被各种专业术语和复杂的数学公式搞得晕头转向。经过几个月的实战摸索&#xff0c;终于总结出一套小白也能快速上手的方法。CPWC&#xff08;相干平面波复合&#xff09;是近年来超声成像领域的热门技术…...

Xinference+tao-8k实战:快速构建文档相似度分析工具

Xinferencetao-8k实战&#xff1a;快速构建文档相似度分析工具 1. 从想法到工具&#xff1a;为什么你需要一个文档相似度分析器 想象一下这个场景&#xff1a;你手头有几百份技术文档、产品说明或者客户反馈&#xff0c;你想快速找出哪些文档在讨论同一个主题&#xff0c;或者…...

UEFI启动画面定制指南:3步实现个性化Windows启动界面

UEFI启动画面定制指南&#xff1a;3步实现个性化Windows启动界面 【免费下载链接】HackBGRT Windows boot logo changer for UEFI systems 项目地址: https://gitcode.com/gh_mirrors/ha/HackBGRT HackBGRT是一款专为UEFI系统设计的Windows启动画面定制工具&#xff0c;…...

影刀经验库共建:5个岗位提效的RPA模板分享

影刀RPA岗位提效模板分享影刀RPA&#xff08;机器人流程自动化&#xff09;能够显著提升企业运营效率&#xff0c;尤其在重复性高、规则明确的任务中表现突出。以下是5个适用于不同岗位的RPA模板&#xff0c;帮助团队快速实现自动化提效。财务岗位&#xff1a;自动化发票处理通…...