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

这篇具有很好参考价值的文章主要介绍了Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


概述

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 方法的介绍如下:
Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法
该函数有两个参数,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 方法的介绍如下:
Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法
该函数有四个参数,通过计算 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;

    /** 当有新的传感器事件时(手机方向改变时调用)调用。 */
    @Override
    public 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();
    }

    /** 当注册传感器的精度发生变化时调用。 */
    @Override
    public 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之传感器(三)方向传感器文章来源地址https://www.toymoban.com/news/detail-404674.html

到了这里,关于Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Only fullscreen opaque activities can request orientation

    关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 未经允许不得转载 我们继续总结学习 基础知识 ,温故知新。 本文记录一次bug解决的过程, Only fu

    2024年03月15日
    浏览(52)
  • Android 设置TabLayout选中后的字体、大小、颜色等设置

    初始化 1)在xml中设置颜色变化 其中,tabTextColor未未选中时的颜色,tabSelectedTextColor为选中时的颜色。 2)对已定义好的TabLayout进行处理。 在监听器中设置样式 在选中时或未选中时,获取已设置的TextView,然后可以去设置需要的大小、加粗等变化。 我做了一个简单的封装,这

    2024年02月12日
    浏览(37)
  • Android窗口层级(Window Type)分析

    Android的窗口Window分为三种类型: 应用Window,比如 Activity 、 Dialog ;子Window,比如 PopupWindow ;系统Window,比如 Toast 、系统状态栏、导航栏等等。 应用Window的Z-Ordered最低,就是在系统中的显示层级最低,然后到子Window,层级最高的是系统Window。层级高的Window会覆盖层级低的W

    2024年02月09日
    浏览(39)
  • Android 工厂模式增加Type-A功能测试

    Android 工厂模式增加Type-A功能测试 收到客户需求想要增加Type-A测试项来验证Type-A功能,具体功能实现参照如下: /vendor/freeme/packages/apps/FreemeFactoryTest/src/com/freeme/factory/usb/TypeAUSB.java       重新编译验证,修改生效,工厂模式Type-A功能验证通过

    2024年02月08日
    浏览(35)
  • Android Studio版本升级后的问题 gradle降级、jdk升级 Compose 与 Kotlin 的兼容性对应关系

    AGPBI: {“kind”:“error”,“text”:“Can’t determine type for tag ‘macro name=“m3_comp_switch_disabled_selected_handle_color”?attr/colorSurface’”,“sources”:[{“file”:“/Users/fausto/.gradle/caches/transforms-3/4948d05d0ff6027d2e3c9f4a6010103b/transformed/material-1.7.0-alpha02/res/values/values.xml”}],“tool”:“Resource and

    2024年02月04日
    浏览(73)
  • npm发布包教程(五):废弃/删除

    npm包发布后可以对包进行废弃或删除操作,废弃和删除的区别在于: 废弃不会将包或版本从npm仓库删除,仍然可以继续下载安装,并在安装的时候会有警示 删除会将包从npm彻底删除,无法被下载安装 无论是废弃还是删除,都包含两个层面: 版本的废弃/删除 包的废弃/删除

    2024年02月07日
    浏览(36)
  • startActivityForResult已被废弃,使用registerForActivityResult替换

    开发中在进行页面跳转时使用startActivityForResult,但是AndroidStudio提示已经deprecated,可以使用registerForActivityResult进行替换 java写法 Kotlin写法

    2024年02月09日
    浏览(54)
  • 废弃的 电信光猫 改为 免费的wifi

    修改为桥接模式即可。 1.修改电脑IP地址与光猫同一网段,例如192.168.1.2 掩码255.255.255.0。 电信光猫默认地址为 192.168.1.1  掩码为 255.255.255.0  2.网线或者无线连接光猫,无线wifi 名称(SSID)和密码 光猫背后都有。 3.浏览器登入光猫IP为  192.168.1.1 (下图我的光猫地址我修改过

    2024年02月14日
    浏览(41)
  • Spring Security 6 配置方法,废弃 WebSecurityConfigurerAdapter

    最近阿里云的项目迁回本地运行,数据库从阿里云的RDS(即Mysql5.6)换成了本地8.0,Redis也从古董级别的2.x换成了现在6,忍不住,手痒,把jdk升级到了17,用zgc垃圾回收器,源代码重新编译重新发布,结果碰到了古董的SpringBoot不支持jdk17,所以有了这篇日志。记录一下SpringBo

    2024年02月01日
    浏览(37)
  • SVN通过备份、过滤、再导入的方式彻底删除废弃目录

    SVN占用的空间随着项目版本迭代越来越大,因为保存了历史记录中的各个版本,所以即使本地把废弃的目录删掉提交,也不会释放出多余的空间,大概率因为操作删除增加了一个版本号,使得占用的空间更大了。 怎么才能让它的空间变小的,最简单粗暴的方式就是丢弃历史记

    2023年04月22日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包