Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法

文章目录

  • 概述
    • getOrientation 方法根据 旋转矩阵R 获取 设备旋转弧度
    • getRotationMatrix 方法根据 地磁场、加速度传感器对象 获取 旋转矩阵R
  • 代码
  • 参考资料


概述

Sensor.TYPE_ORIENTATION 常数在 API 8 中已弃用,官方推荐使用 SensorManager.getOrientation() 替代。关于 Orientation Sensor(被弃用的方向传感器) 在官方文档中的概述里有这样一句话:

The orientation sensor is software-based and derives its data from the accelerometer and the geomagnetic field sensor. (方向传感器是基于软件的,并且它的数据是通过加速度传感器和磁场传感器共同获得的)

上面的描述其实少了一个重要角色,即 SensorManager.getOrientation()方向传感器 在被弃用之前,正是通过 SensorManager.getOrientation() 来借助 加速度传感器(Sensor.TYPE_ACCELEROMETER)地磁场传感器(TYPE_MAGNETIC_FIELD) 的数据得到的。


getOrientation 方法根据 旋转矩阵R 获取 设备旋转弧度

官方文档中,对于 getOrientation 方法的介绍如下:
在这里插入图片描述
该函数有两个参数,Rvalues。传入时 R 有具体值而 values 是空的,然后在方法内部根据 旋转矩阵R 计算设备的方向,将结果存储在 values 中:

  • values[0] 记录着手机围绕 Z 轴的旋转弧度
  • values[1] 记录着手机围绕 X 轴的旋转弧度
  • values[2] 记录着手机围绕 Y 轴的旋转弧度

而后可以通过 Math.toDegrees() 方法将旋转弧度转化为角度。

但是这里还有个问题,旋转矩阵R 的值从何而来呢?事实上,其值通过我们之前提到 加速度传感器(Sensor.TYPE_ACCELEROMETER)地磁场传感器(TYPE_MAGNETIC_FIELD) 的获得。

首先通过 SensorEvent 对象获得两个传感器对象 Sensor ,一个是 加速度传感器,另一个是 地磁场传感器

public void onSensorChanged(SensorEvent event) {// SensorEvent:保存精度(accuracy)、传感器类型(sensor)、时间戳(timestamp)// 以及不同传感器(Sensor)具有的不同传感器数组(values)。SensorManager.getOrientation(r, values);// TYPE_MAGNETIC_FIELD:描述磁场传感器类型的常量。if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {geomagnetic = event.values; // 地磁场传感器对象}// TYPE_ACCELEROMETER:描述加速度传感器类型的常量。if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {gravity = event.values; // 加速度传感器对象}
}

getRotationMatrix 方法根据 地磁场、加速度传感器对象 获取 旋转矩阵R

之后通过这两个对象结合 SensorManager.getRotationMatrix() 方法获取 旋转矩阵R 的具体值。官方文档中,对于 getRotationMatrix 方法的介绍如下:
在这里插入图片描述
该函数有四个参数,通过计算 gravitygeomagnetic 得到 旋转矩阵R。(第二个参数 倾斜矩阵I 用于将磁场数据转换进实际的重力坐标系中,一般默认设置为NULL即可。)


代码

/** 方向传感器 */
public class MyOrientationListener implements SensorEventListener {private static final String TAG = "WeatherActivity";private final Context context;private SensorManager sensorManager;private Sensor magneticSensor, accelerometerSensor;private float[] gravity = new float[3];private float[] geomagnetic= new float[3];private OnOrientationListener onOrientationListener;  //内部接口实现回调private double lastX;/** 当有新的传感器事件时(手机方向改变时调用)调用。 */@Overridepublic void onSensorChanged(SensorEvent event) {Log.e(TAG, "onSensorChanged 开始");// SensorEvent:保存精度(accuracy)、传感器类型(sensor)、时间戳(timestamp)// 以及不同传感器(Sensor)具有的不同传感器数组(values)。// TYPE_MAGNETIC_FIELD:描述磁场传感器类型的常量。if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {geomagnetic = event.values;Log.e(TAG, "onSensorChanged 得到磁场传感器: " + Arrays.toString(geomagnetic));}// TYPE_ACCELEROMETER:描述加速度传感器类型的常量。if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {gravity = event.values;Log.e(TAG, "onSensorChanged 得到加速度传感器: " + Arrays.toString(gravity));}getValue();}/** 当注册传感器的精度发生变化时调用。 */@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}/** 通过加速度和磁场变化获取方向变化的信息 */public void getValue() {//初始化数组float[] values = new float[3]; // 用来保存手机的旋转弧度float[] r = new float[9]; // 被填充的旋转矩阵// 传入gravity和geomagnetic,通过计算它们得到旋转矩阵R。// 而第二个参数倾斜矩阵I是用于将磁场数据转换进实际的重力坐标系中的,一般默认设置为NULL即可。SensorManager.getRotationMatrix(r, null, gravity, geomagnetic);// 根据旋转矩阵R计算设备的方向,将结果存储在values中。// values[0]记录着手机围绕 Z 轴的旋转弧度,// values[1]记录着手机围绕 X 轴的旋转弧度,// values[2]记录着手机围绕 Y 轴的旋转弧度。SensorManager.getOrientation(r, values);Log.e(TAG, "getValue R: " + Arrays.toString(r));Log.e(TAG, "getValue values: " + Arrays.toString(values));// 旋转弧度转为角度float pitch = (float) Math.toDegrees(values[0]);Log.e(TAG, "getValue pitch: "+ pitch);if (Math.abs(lastX) > 1.0) { // 设置条件防止频繁回调onOrientationListener.onOrientationChanged(pitch);}lastX = pitch;}public interface  OnOrientationListener{void onOrientationChanged(float x);}public void setOnOrientationListener(OnOrientationListener onOrientationListener){this.onOrientationListener = onOrientationListener;Log.e(TAG, "setOnOrientationListener: 接口设置完成");}public MyOrientationListener(Context context){this.context=context;}public void onStart(){sensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);if (sensorManager != null) { // 初始化两个传感器// getDefaultSensor:获取Sensor,使用给定的类型和唤醒属性返回传感器。magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);}if (magneticSensor != null) {assert sensorManager != null;sensorManager.registerListener(this, magneticSensor,SensorManager.SENSOR_DELAY_UI);}if (accelerometerSensor != null) {assert sensorManager != null;sensorManager.registerListener(this, accelerometerSensor,SensorManager.SENSOR_DELAY_UI);}}public void onStop(){sensorManager.unregisterListener(this); // 传感器解除绑定}
}

参考资料

传感器的相关知识讲的很详细

Android之传感器(三)方向传感器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JAVA 开发小问题】 | String操作合集

文章目录截取特定两个字符之间的字符串截取特定两个字符之间的字符串 利用正则表达式,图片来源

uniapp 刷新后数据都没有了_环境温度传感器都没有连接,竟然还会有数据?

福田欧曼GTL(福康发动机、康明斯2880系统)匹配ECoffit尿素泵●故障现象:OBD故障灯点亮,不烧尿素,油耗高,动力不足●故障码:●维修分析:①故障指出加热器问题,摸下尿素箱温度,发现烫手…

保姆级教学!Xcode 配置 OpenGL 环境

文章目录GLFW获取 GLFWGLAD获取 GLAD在 Xcode 中配置下载好的 GLFW 和 GLAD配置流程检测是否配置成功无关配置的题外话——Xcode 下安全的删除移动操作GLFW Graphics Library Framework(图形库框架),可以让我们通过其封装好的 通用API 来正确…

Android入门(17)| 百度提供的 Android定位SDK

文章目录配置百度提供的 Android定位SDK用于发布的 SHA1用于测试的 SHA1使用百度定位实例配置百度提供的 Android定位SDK 详情参见官方文档,这里仅对获取 SHA1 做详细介绍: 用于发布的 SHA1 用于测试的 SHA1 使用百度定位实例 public class LocationAc…

ios 不被遮挡 阴影_为何你没见到日环食?你不知道的天象常识原来还有这么多 | 返朴...

关注风云之声提升思维层次导读说好的日环食呢,为什么上周很多人只等到了日偏食?日食月食的时间和种类是怎么预测的?你真的弄懂了各种日食和月食的成因吗?你了解它们有什么区别和联系,又遵循什么样的时间规律吗? 日食和月食发生的频率一样吗…

初识贝塞尔(bezier)曲线

文章目录资料援引贝塞尔曲线的用途一阶贝塞尔(bezier)曲线二阶贝塞尔(bezier)曲线三阶贝塞尔(bezier)曲线高阶贝塞尔(bezier)曲线三阶贝塞尔曲线求插值(Slerp&#xff09…

python代码测试 vim_用 Hypothesis 快速测试你的 Python 代码

点击上方“Python编程时光”,选择“加为星标”第一时间关注Python技术干货!介绍无论你使用哪种编程语言或框架,测试都非常重要。Hypothesis是 Python 的一个高级测试库。它允许编写测试用例时参数化,然后生成使测试失败的简单易懂…

Mac 下 CMake 的配置与使用

文章目录安装与配置编译单个源文件编译前的准备开始编译编译多个源文件多个源文件在同一目录下多个源文件在不同目录下math 目录下的 CMakeLists.txt根目录的 CMakeLists.txtoption 选项导入外部库本地导入(find_package)外部导入(FetchConte…

五轴编程_沙井万丰数控数控编程五轴编程那个软件好用

沙井万丰数控数控编程五轴编程那个软件好用设计需要掌握很高很全面的知识和技能,模具做的好,产品质量好,模具结构合理,生产效率高,工厂效益好。正因如此,模具技术工在外打工的工资都非常的高。少则每月几千…

Linux学习:第二章-Linux安装

一虚拟机使用 VMware主要特点: 1、不需要分区或重新开机就能在同一台PC上使用两种以上的操作系统 2、本机系统可以与虚拟机系统网络通信 3、可以设定并且随时修改虚拟机操作系统的硬件环境 二安装方式 图形安装:直接回车 字符安装:linux tex…

keil3如何放大字体_国潮海报不会做?送你国风字体+图案笔刷+PSD素材+包装样机...

有很多朋友都问带鱼,国潮风的海报到底应该怎么做呢?首先你要知道什么是国潮风:国潮风就是现代文化和古代文化的碰撞,是年轻人的态度!那么应该如何构图如何设计呢?如何配色如何搭配字体呢?这些方…

Google 开源项目风格指南学习笔记——C++篇

文章目录前言0. 缩写名词解释1. 头文件1.1. Self-contained 头文件1.2. 头文件保护1.3. 前置声明1.4 内联函数1.5. #include 的路径及顺序2. 作用域2.1. 命名空间2.2. 非成员函数、静态成员函数和全局函数2.3. 局部变量2.4. 静态和全局变量3. 类3.1. 构造函数的职责3.2. 隐式类…

hiveserver2启动不起来_给爱车配个充电宝,70迈汽车应急启动电源,让你远离搭电小广告...

说到汽车应急启动其实我有切身的痛,在哈尔滨零下35的严冬,晚上带着女神吃完饭,高高兴兴地吃完以后一上车,发现电瓶被冻没电了,天知道当时有多尴尬。马上叫了保险公司过来给搭电,结果在饭店从晚上8点一直等到…

Windows 下 VS 配置 OpenGL 环境

文章目录前言获取 GLFW打开 VS前言 感谢B站同学搬运YouTube上的教学视频。 获取 GLFW 从官网上下载GLFW macOS下64位二进制文件 打开 VS 新建解决方案 OpenGL test,并在解决方案中新建文件夹 Dependencies: 从下载好的 glfw 文件夹中找到最新版链接…

ubuntu 网卡双网口 配置_无线网卡m2 ngff keya keye、minipcie接口改转多口有线网卡实现软路...

小型主板及笔记本中的无线网卡m2ngffkeyakeye接口(CNVI除外)通过m2ngffkeyae转接pcie1x转接板,或者无线网卡的minipcie接口,通过minipcie转接pcie1x转接板可以改装有线网卡板卡,来实现软路由功能。m2ngffkeyae转接pcie…

OpenGL | 通过绘制一个三角形来入门 OpenGL 图形渲染管线

文章目录前言什么是 OpenGl ?回顾openGL 的 Object显存结构工作阶段通过顶点缓冲对象将顶点数据初始化至缓冲中标准化设备坐标顶点缓冲对象 VBOglGenBuffersglBindBufferglBufferData建立了一个顶点和一个片段着色器着色器是什么?为什么需要使用着色器&a…

javascript特效_如何在网页添加鼠标点击特效

经常有同学问我怎么做到的,本论坛属于DZ当然用的是插件啦。偶然在网上找到一个关于wordpress的特效代码,分享给大家。WordPress 添加鼠标点击特效实际上这种教程在网上搜索一下有一大堆,已经是各大博主玩烂的东西了。不过既然给自己的博客加上…

android nio debug模式正常 release包crash_Flutter包大小治理上的探索与实践

Flutter作为一种全新的响应式、跨平台、高性能的移动开发框架,在性能、稳定性和多端体验一致上都有着较好的表现,自开源以来,已经受到越来越多开发者的喜爱。但是,Flutter的引入往往带来包体积的增大,给很多研发团队带…

sam格式的结构和意义_各种格式的练字本,对写字真有帮助吗

图片来源于笔势通各种格式的练字本现在越来越多,目的主要是便于学生把握好笔画的位置和布局,从而把整个字的结构处理好,常见的有米字格,回宫格等。这些练字本对于初学者来说肯定是有帮助的,特别是低年级学生。当然随着…

硬件结构图_那曲地表水电子除垢仪结构图

那曲地表水电子除垢仪结构图水处理设备也应断电停止使用,系统长期停止运行或季节性停止运行,在系统停止运行前,在水中投加适量缓蚀剂,并采取满水湿保护的措施,以减小腐蚀,保护系统。开启进水阀检查无误后电…