Android强制设置所有应用显示方向,忽略应用本身的设置

在ROM定制系统开发过程中经常会遇到需要改变第三方应用显示方向的需求,比如抖音这种手机APP都是强制竖屏的,不会跟随屏幕旋转。但在一些平板方案开发中需要能横屏显示,或者需要跟随屏幕旋转方向动态切换横竖屏显示。这时就需要在系统层面去处理了。

先梳理一下屏幕旋转时系统处理的大致流程:

Android 屏幕旋转处理是一个涉及硬件、系统服务、应用层的复杂过程。以下是屏幕旋转处理流程的概述:

  1. 硬件层 (G-sensor):设备中的加速度传感器(G-sensor)检测到物理方向和加速度变化,判断设备的旋转方向 。

  2. 系统服务 (Sensor Service):Sensor Service 管理和提供传感器数据。当 G-sensor 检测到方向变化时,数据会传递到 Sensor Service 。

  3. 方向监听器 (Orientation Listener):应用可以注册方向监听器来监听设备的方向变化,通过 Sensor Service 获取传感器数据,并计算设备的方向 。

  4. 窗口管理器 (Window Manager):窗口管理器负责处理屏幕旋转,调整显示方向以确保用户界面正确显示 。

  5. 配置改变 (Configuration Change) :屏幕旋转会触发应用的配置改变事件,导致活动(Activity)重新创建,并触发 onConfigurationChanged 回调 。

  6. Activity 生命周期处理 :屏幕旋转导致配置改变时,活动会经历生命周期的重新创建阶段,如 onDestroy、onCreate、onStart 和 onResume 。

  7. 重新绘制界面:屏幕旋转后,系统请求重新绘制界面以适应新的方向,应用的布局会根据新的配置进行重新计算和绘制 。

  8. 处理保存的状态 :应用需要处理保存和恢复状态,以确保用户数据的连续性,Android 提供了 onSaveInstanceState 和 onRestoreInstanceState 方法 。

在代码层面,可以通过 setRequestedOrientation 方法设置屏幕方向,此方法等同于在 AndroidManifest.xml 中设置 android:screenOrientation 属性 。设置之后,可以通过 onConfigurationChanged 方法来响应方向变化 。

另外,系统设置中的自动旋转开关会影响应用的屏幕旋转行为。当自动旋转关闭时,无论设备如何旋转,应用界面都不会旋转,除非应用通过代码强制旋转 。用户可以通过下拉通知栏快速切换自动旋转的开启和关闭 。

我们需要做的是在上述第4步中处理,具体修改如下:

frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.java中的

rotationForOrientation(@ScreenOrientation int orientation,@Surface.Rotation int lastRotation)方法就是处理应用中的显示方向设置的,第一个参数orientation就是应用设置的方向,在此方法中进行拦截重写即可。代码如下:

复制代码
    /**
     * Given an orientation constant, returns the appropriate surface rotation, taking into account
     * sensors, docking mode, rotation lock, and other factors.
     *
     * @param orientation  An orientation constant, such as
     *                     {@link ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
     * @param lastRotation The most recently used rotation.
     * @return The surface rotation to use.
     */
    @VisibleForTesting
    @Surface.Rotation
    int rotationForOrientation(@ScreenOrientation int orientation,
            @Surface.Rotation int lastRotation) {
        ProtoLog.v(WM_DEBUG_ORIENTATION,
                "rotationForOrientation(orient=%s (%d), last=%s (%d)); user=%s (%d) %s",
                ActivityInfo.screenOrientationToString(orientation), orientation,
                Surface.rotationToString(lastRotation), lastRotation,
                Surface.rotationToString(mUserRotation), mUserRotation,
                mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
                        ? "USER_ROTATION_LOCKED" : "");

        // 重置orientation,强制所有应用跟随屏幕旋转,也可以设置成强制横屏或竖屏固定
        orientation = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
        //在系统原有的检查是否设置了固定屏幕之前设置,否则系统设置中的开关就无效了
        if (isFixedToUserRotation()) { 
            return mUserRotation;
        }

        int sensorRotation = mOrientationListener != null
                ? mOrientationListener.getProposedRotation() // may be -1
                : -1;
        if (sensorRotation < 0) {
            sensorRotation = lastRotation;
        }
        ...
}

这里顺带记录一下我开发过程中遇到的另一个问题,有些设备屏幕旋转后不会回调

复制代码
onConfigurationChanged()方法,而是重新走onCreate()流程了,Manifest中开始是这样设置的:
复制代码
android:configChanges="orientation|screenSize",此设置大部分设置都可以正常回调,后来查询得知加上screenLayout配置就都可以了,如下:
复制代码
android:configChanges="orientation|screenSize|screenLayout"
相关推荐
baidu_247438611 小时前
Android 自定义竖直的虚线
android
传奇开心果编程2 小时前
【Jetpack Compose娓娓道来】 第25课:ViewModel就是UI界面的大脑
android·kotlin·移动开发·jetpack compose·编程语言理论·编程框架·声明式ui
马立杰2 小时前
PHP 未授权 RCE 应急响应:CVE-2026-109618 CVE-2026-109619 排查与加固实战
android·开发语言·php
NamoAmitabha1282 小时前
安装“编译器环境”(Android Studio)--deepseek--Cocos --Creator3.8.8
android·ide·android studio
聚美智数3 小时前
文档转换 API‑文档转 PDF‑PDF 转文档‑异步文档处理‑文件格式迁移‑转换结果回调推送 API 接口介绍
android·java·pdf
booboosui4 小时前
Android 上的无人回合:只放开 2 类工具,宁可空手
android
事圆则缓6 小时前
Android 性能排查实战:怎么看内存抖动、CPU 占用和 FPS
android
mmsx6 小时前
Android 三类「看着无关」的故障:大事务、UI 阻塞与 ViewModel 作用域
android·ui
换元不配限6 小时前
Android 休眠与唤醒完全指南:从手机到 IoT 设备的实战解析
android·物联网·智能手机·alarmmanager·wakelock·workmanager·休眠和唤醒
通信侠7 小时前
android 16触摸提示音Back虚拟按键无声
android