Android(安卓)8.1 系统按键音
最近接到的任务:实现手机键盘按键音功能
可是网上查到的资料太少,可能是现在没什么带键盘的Android设备了
一开始我以为系统会做好这些东西,是需要找到一个开关,写一个默认值就行,然鹅事情并没有这么简单,分析源码好像只找到锁屏按键、屏幕点击的点击音。。。只能自己写这功能了!
话不多说,开始分析按键流程
具体的流程网上的资源特别多,就不在此一一赘述了。
流程涉及的主要方法和类:
DecorView -> dispatchKeyEvent()
Activity -> dispatchKeyEvent()
ViewGroup -> dispatchKeyEvent()
View -> dispatchKeyEvent()
KeyEvent -> dispatch()
View -> onKeyDown/Up()
事件会在上述流程中传递,那么我们想要发出按键音,只需要在上述流程中找到一个合适的地方,播放音量资源。
那什么是,合适的地方呢,我的第一要素是参照系统自带的功能设计。
那我就在上述涉及到的类里开始寻找。
1、分析锁屏音,能不能仿造
经过对锁屏键的跟踪,发现它的音量播放不在按键流程里,而是在锁屏流程里,而我们要避免过于复杂的流程,所以先暂时排除。
2、分析触摸提示音、能不能仿造
那就跟踪view的touch dispatch看看吧
发现目标
playSoundEffect(SoundEffectConstants.CLICK)
frameworks/base/core/java/android/view/View.java
按键音在View.java里实现了,用的playSoundEffect()这个方法,那我们就也用这个方法来实现我们的按键音吧
View ----> dispatchKeyEvent()
按键会在view的dispatchKeyEvent进行分发处理,那么我们就在这个函数里对键值进行判断吧:
public boolean dispatchKeyEvent(KeyEvent event) { final int keyCode = event.getKeyCode(); if (event.getAction() != KeyEvent.ACTION_DOWN) {switch (keyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_WAKEUP: case KeyEvent.KEYCODE_PAIRING: case KeyEvent.KEYCODE_STEM_1: case KeyEvent.KEYCODE_STEM_2: case KeyEvent.KEYCODE_STEM_3: case KeyEvent.KEYCODE_0: case KeyEvent.KEYCODE_1: case KeyEvent.KEYCODE_2: case KeyEvent.KEYCODE_3: case KeyEvent.KEYCODE_4: case KeyEvent.KEYCODE_5: case KeyEvent.KEYCODE_6: case KeyEvent.KEYCODE_7: case KeyEvent.KEYCODE_8: case KeyEvent.KEYCODE_9: case KeyEvent.KEYCODE_STAR: case KeyEvent.KEYCODE_POUND: case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_DEL: case KeyEvent.KEYCODE_CAPS_LOCK: case KeyEvent.KEYCODE_SCROLL_LOCK: case KeyEvent.KEYCODE_FUNCTION: case KeyEvent.KEYCODE_F7: { playSoundEffect(5); } } }
OK!编译好push到手机里就实现了,按下按键就有像点击屏幕一样的“突突突”音了。。。
好,现在来分析playSoundEffect(SoundEffectConstants.CLICK)
这个参数就是播放音效的关键了,那就来分析 SoundEffectConstants
这里面就定义了点击、上、下、左、右的5种音效
public static final int CLICK = 0; public static final int NAVIGATION_LEFT = 1; public static final int NAVIGATION_UP = 2; public static final int NAVIGATION_RIGHT = 3; public static final int NAVIGATION_DOWN = 4; public static final int NAVIGATION_KEYPRESS = 5;//add keypress effect
playSoundEffect函数才是真正的播放的关键地方,跟进
frameworks\base\core\java\android\view\ViewRootImpl.java
@Override public void playSoundEffect(int effectId) { checkThread(); try { final AudioManager audioManager = getAudioManager(); switch (effectId) { case SoundEffectConstants.CLICK: audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); return; case SoundEffectConstants.NAVIGATION_DOWN: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); return; case SoundEffectConstants.NAVIGATION_LEFT: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); return; case SoundEffectConstants.NAVIGATION_RIGHT: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); return; case SoundEffectConstants.NAVIGATION_UP: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); return; case SoundEffectConstants.NAVIGATION_KEYPRESS: audioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD); return;.........
case SoundEffectConstants.NAVIGATION_KEYPRESS:
audioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
return;
这段就是我增加的音效,之所以是AudioManager.FX_KEYPRESS_STANDARD,
这就是我在跟AudioManager.FX_KEY_CLICK的时候在AudioManager里面发现的系统有对按键音原来有过分配音效,可能是因为键盘逐渐弃用,而对按键音不再适配了吧。
好,到此为止,按键音功能已经实现,本文到此为止,但是后续的拓展的东西还很多,比如AudioManager里面去实现自定义的音乐资源作为提示音,以及这样实现会不会带来不好的影响我也没有深入研究,作为新人,希望记录下来自己的工作,如有错误的地方希望大家指正!
谢谢!
更多相关文章
- Android最新敲诈者病毒分析及解锁
- Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析
- Android(安卓)记一次解决问题的过程:从源码中分析永远是解决问题
- Android(安卓)项目实践(一)——开发流程
- Android窗口管理服务WindowManagerService显示窗口动画的原理分
- (6) Android中Binder调用流程 --- Binder驱动总结
- android adb 流程原理代码分析(一)
- Android基础学习【历史流程重走】 ---- Android入门基础(一)
- 【理论】【转】App工程结构搭建:几种常见Android代码架构分析