最近公司要升级 android 8.1 版本,虽说有以前成熟的版本(android 4.4,android 7.1 等)代码大同小异,但是由于代码的不熟悉,加上是第一次进行版本验证,还是有不小的挑战,好在功夫不负有心人.话不多说,直接进入主题.
Android 音量调节网上也有许多资料,想必大家也清楚,通过遥控音量按键调用 AudioManager.java 中的 public void preDispatchKeyEvent(KeyEvent event, int stream) 函数
然后调用 adjustSuggestedStreamVolume(),这个 adjustSuggestedStreamVolume() 直接调用到 AudioService.java 中的 adjustSuggestedStreamVolume() 进行音量的具体操作,把音量值传递到 AudioManagerPolicy.cpp 去实现.但是若 preDispatchKeyEvent() 都没调用,这一切都是空谈,没错,我就遇到这个大坑,毕竟我主要是搞底层,上层应用,java 的东西都是现学现用,网上也没有查不到这个函数是怎么调用的,f-u-c-k!
硬着头皮,赖着性子查找,通过 framework/base / 目录 grep preDispatchKeyEvent 关键字,查到 AudioManager.java 中的 preDispatchKeyEvent 是由 core/java/com/android/internal/policy/PhoneFallbackEventHandler.java 调用,而这个函数没有做什么实际的操作,它在由 core/java/android/view/ViewRootImpl.java 调用
通过加在 processKeyEvent() 加 log 发现,这个函数也没有被调用,擦,懵逼了.问了师傅后,发现方向错了,因为上层按键的派发是 phonewindowsmanager 那边传递过来,所以查找方向可能有错.
那就回到最初的起点,那就对比下 8.0 的代码,在 AudioService.java 中 adjustSuggestedStreamVolume() 加堆栈,
找到
原来在 PhoneWindowManager.java 中调用过来的,继续找到 dispatchDirectAudioEvent 如下地方调用过来的,这里有个判断的方法,通过对比发现,8.1 的变量为 mUseTvRouting 为 flase,而 8.0 的为 true,所以 8.1 的没有调用!!!
其实到这里问题已经很明显了,查找 mUseTvRouting 赋值的地方.
AudioSystem.PLATFORM_TELEVISION 的定义为 2,那显然 AudioSystem.getPlatformType(mContext) 不为 2,继续更进 AudioSystem.getPlatformType(mContext) 代码,具体实现在 AudioSystem.java 中,
走到了 PLATFORM_DEFAULT 的 case,那就不满足 hasSystemFeature(PackageManager.FEATURE_LEANBACK) 这个条件,显然 FEATURE_LEANBACK 是 PackageManager 类的一个变量,grep 查找关键字 FEATURE_LEANBACK,找到在该定义的地方
这个字符串 android.software.leanback 很明显是 xml 配置文件中定义,于是到产品配置 xml 的目录下去查找,找到这个字符串被注释掉了,汗~~~ 问题搞定.
来源: http://www.jianshu.com/p/1ab67f979007