首先尝试的一种切换刷新率的方法
1 | // 获取WindowManager对象 |
但是很显然,如果这个方法可行,就不会再有一篇文章来记录了
厂商硬件 API
我手上有雷鸟的 AR 眼镜,有 Xreal 的 AR 眼镜
这些眼镜厂商都有自己的安卓 App,然后配合眼镜内的固件
插个题外话,这两家厂商都不开放 Android SDK,硬生生的把自己的生态给堵死
他们从未想过如果开放 API,会有开发者借助 API 开发出各种各样的可以加强他们眼镜功能的 App
也不知道他们怎么想的吧,程序员永远理解不了产品经理
觉得自己有几百人的研发,能把自己的生态弄得很好
大概是制定一些协议,通过串口通信的方式,来控制眼镜
从表现上来说,当接上对应的眼镜进入 App 时,眼镜会自动切换为 3D 模式
这个就是 AR 的 SDK 完成的
我问过 Xreal 要过接口,基本上是不愿意给了
抛开 AR 眼镜本身来看,他们的生态就是一坨,Beam Pro 的设计也是一坨
闭关锁国,取死之道
Rokid
Rokid 是跟我合作的,唯一一个愿意提供 Android SDK 的,但是整个过程也不是很顺畅
通过这个 SDK 可以控制 Rokid 的 AR 眼镜
这个时候,我其实是有点期望的,以为通过 SDK 可以直接修改刷新率
还是由于各种信息差导致的,他们的产品经理咬定可以修改
但其实他并不懂技术,导致 SDK 给到我后
并不能更改到 2D 1080P 90/120 hz 的刷新率
后来他把他们的研发拉了进来
沟通上也不是很顺畅
并且从研发到研发的沟通,都还有很多信息差
细节后面补上
他们的接口是隐藏的
并且很多参数是枚举类,只有到最底层,才通过枚举的值来调用 JNI 的函数
SDK 导入到 Android 工程后,根本无法看到下面的接口
经过我对 SDK 的逆向,才写出了这些代码
1 | RKGlassDevice mRKGlassDevice = RKGlassDevice.getInstance(); |
通过一系列的反射,终于把这个函数给掉通了,但是我再通过 Android API 获取 Display 的刷新率,并没有任何变化
只发现有一些值不一样
adb shell cmd display get-displays
1 | # 调用接口前 |
啊这,调用接口后,眼镜 DisplayInfo 中的 Mode 变多了,仅此而已
而 XREAL 的眼镜默认就有多种 Mode,我调用接口后得到了其他家眼镜默认的状态?
也就是说,这个接口并不能切换刷新率
折腾半天,得出一个结论
调用这个接口和长按眼镜的音量+键,效果一样
我直接 What,那最初是不是就应该告知我这个信息
而为什么调用接口又能设置为 3D 3840x1080 90hz 呢
因为对于 3D 模式,通过串口通信到眼镜内的固件后,这个眼镜就变成了一个只有 3D 模式的眼镜
AR 眼镜对手机还是 PC 来说,都只是一个普通的显示器
如果这个显示器只支持 3840x1080 90hz,你接上手机,它应该亮还是不亮
如果亮的话,眼镜的显示信息也就必然是 3840x1080 90hz
这个对于 PC 来说也是一样
所以安卓自然而然的切换到了 3D,并且有高刷
所以关键是,如果要实现通过 AR SDK 修改刷新率,硬件那边就将设备设置为只有某个刷新率的 Mode 即可,但是很显然,这个就得给他们加需求了
也不知道他们愿不愿意配合,因为大部分 AR 厂商的任何人,包括产品,研发,运营,都会觉得这些都是伪需求,自己的生态已经无敌了,几句沟通就要把同行踩个遍(指XREAL)
所以,这条路,估计也难走通
调研资料
https://www.youtube.com/watch?v=YSDBKqoL0O8
这个视频中的设备,是能够直接在系统中切换外接显示器的刷新率的,后续我的小米如果能 Root 的话,我也想研究下 AOSP 官方镜像(就是刷 ROM)支不支持切换
也就是系统层,其实是有入口可以切换刷新率的,这个入口指 Android 比较底层的 API
而国内厂商嘛,任何 Google 本身系统有的东西,当然是全砍了,不然怎么能让你知道用的他们的手机
部分调研源码,链路分析待补
ADB Shell
安卓有一个自带的 adb 命令,藏得非常深
执行 adb shell cmd display 可以看到支持的功能
1 | Display manager commands: |
提取其中关键的几个命令
1 | set-user-preferred-display-mode WIDTH HEIGHT REFRESH-RATE DISPLAY_ID (optional) |
并且我还多查了几个命令以及他们的源码实现
adb shell cmd display set-match-content-frame-rate-pref 2
这个命令
MATCH_CONTENT_FRAMERATE_ALWAYS
Added in API level 31
public static final int MATCH_CONTENT_FRAMERATE_ALWAYS
Refresh rate switches between all refresh rates are allowed even if they have visual interruptions for the user.
Constant Value: 2 (0x00000002)
MATCH_CONTENT_FRAMERATE_NEVER
Added in API level 31
public static final int MATCH_CONTENT_FRAMERATE_NEVER
No mode switching is allowed.
Constant Value: 0 (0x00000000)
MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY
Added in API level 31
public static final int MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY
Only refresh rate switches without visual interruptions are allowed.
Constant Value: 1 (0x00000001)
MATCH_CONTENT_FRAMERATE_UNKNOWN
Added in API level 31
public static final int MATCH_CONTENT_FRAMERATE_UNKNOWN
Match content frame rate user preference is unknown.
Constant Value: -1 (0xffffffff)
尝试将这个值设置为 2
再通过 set-user-preferred-display-mode 命令设置刷新率,都没有任何变化
目前手机切换刷新率都以失败告终
所以目前