Android Input输入系统之五:KeyEvent按键调节音量加减流程

本文主要是介绍Android Input输入系统之五:KeyEvent按键调节音量加减流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Android按键Input KeyEvent》
《Android Input输入系统之一:KeyEvent事件监听及事件分发流程》
《Android Input输入系统之二:KeyEvent注入事件及事件分发流程》
《Android Input输入系统之三:KeyEvent事件分发和上层应用层对事件的接收》
《Android Input输入系统之四:KeyEvent事件中的InputChannel通信》
《Android Input输入系统之五:KeyEvent按键调节音量加减流程》

在上一章节,我们讲到了将按键消息传递分发给View。

在ViewPostImeInputStage阶段,调用了processKeyEvent(),其中:

// Deliver the key to the view hierarchy.
if (mView.dispatchKeyEvent(event)) {return FINISH_HANDLED;
}

通过dispatchKeyEvent将按键消息分发给了View.

那我们就从dispatchKeyEvent()说起。

View的根类是DecorView。

最终都会调用到DecorView中的dispatchKeyEvent()。
frameworks\base\core\java\com\android\internal\policy\DecorView.java

    @Overridepublic boolean dispatchKeyEvent(KeyEvent event) {final int keyCode = event.getKeyCode();final int action = event.getAction();final boolean isDown = action == KeyEvent.ACTION_DOWN;if (isDown && (event.getRepeatCount() == 0)) {// First handle chording of panel key: if a panel key is held// but not released, try to execute a shortcut in it.if ((mWindow.mPanelChordingKey > 0) && (mWindow.mPanelChordingKey != keyCode)) {boolean handled = dispatchKeyShortcutEvent(event);if (handled) {return true;}}// If a panel is open, perform a shortcut on it without the// chorded panel keyif ((mWindow.mPreparedPanel != null) && mWindow.mPreparedPanel.isOpen) {if (mWindow.performPanelShortcut(mWindow.mPreparedPanel, keyCode, event, 0)) {return true;}}}if (!mWindow.isDestroyed()) {final Window.Callback cb = mWindow.getCallback();final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event): super.dispatchKeyEvent(event);if (handled) {return true;}}return isDown ? mWindow.onKeyDown(mFeatureId, event.getKeyCode(), event): mWindow.onKeyUp(mFeatureId, event.getKeyCode(), event);}

cb 是一个Activity或者Dialog对象。用于回调上层应用app中监听的dispatchKeyEvent();

如果经过所有应用层的View,Activity等都没有消耗掉key事件,最终会走到PhoneWindow中:

return isDown ? mWindow.onKeyDown(mFeatureId, event.getKeyCode(), event): mWindow.onKeyUp(mFeatureId, event.getKeyCode(), event);

frameworks\base\core\java\com\android\internal\policy\PhoneWindow.java

    /*** A key was pressed down and not handled by anything else in the window.** @see #onKeyUp* @see android.view.KeyEvent*/protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) {/* ***************************************************************************** HOW TO DECIDE WHERE YOUR KEY HANDLING GOES.** If your key handling must happen before the app gets a crack at the event,* it goes in PhoneWindowManager.** If your key handling should happen in all windows, and does not depend on* the state of the current application, other than that the current* application can override the behavior by handling the event itself, it* should go in PhoneFallbackEventHandler.** Only if your handling depends on the window, and the fact that it has* a DecorView, should it go here.* ****************************************************************************/final KeyEvent.DispatcherState dispatcher =mDecor != null ? mDecor.getKeyDispatcherState() : null;//Log.i(TAG, "Key down: repeat=" + event.getRepeatCount()//        + " flags=0x" + Integer.toHexString(event.getFlags()));switch (keyCode) {case KeyEvent.KEYCODE_VOLUME_UP:case KeyEvent.KEYCODE_VOLUME_DOWN:case KeyEvent.KEYCODE_VOLUME_MUTE: {// If we have a session send it the volume command, otherwise// use the suggested stream.if (mMediaController != null) {mMediaController.dispatchVolumeButtonEventAsSystemService(event);} else {getMediaSessionManager().dispatchVolumeKeyEventAsSystemService(event,mVolumeControlStreamType);}return true;}//省略一部分代码//...}//省略一部分代码//...}

因为我们只分析音量的调节,这里列出来了KeyEvent.KEYCODE_VOLUME_UP的按键消息。

下面即使我们比较熟悉的音量调节流程了。我们走一遍这个流程。

这个流程分两个:
//UI 按钮画面上进行音量调节
dispatchVolumeButtonEventAsSystemService()

//硬件按键进行调节
dispatchVolumeKeyEventAsSystemService()

我们需要关注的是按键的调节。按钮调节逻辑简单跟一下。

按钮执行音量调节

dispatchVolumeButtonEventAsSystemService
frameworks\base\media\java\android\media\session\MediaController.java

public void dispatchVolumeButtonEventAsSystemService(@NonNull KeyEvent keyEvent) {switch (keyEvent.getAction()) {case KeyEvent.ACTION_DOWN: {int direction = 0;switch (keyEvent.getKeyCode()) {case KeyEvent.KEYCODE_VOLUME_UP:direction = AudioManager.ADJUST_RAISE;break;case KeyEvent.KEYCODE_VOLUME_DOWN:direction = AudioManager.ADJUST_LOWER;break;case KeyEvent.KEYCODE_VOLUME_MUTE:direction = AudioManager.ADJUST_TOGGLE_MUTE;break;}try {mSessionBinder.adjustVolume(mContext.getPackageName(), mCbStub, true, direction,AudioManager.FLAG_SHOW_UI);} catch (RemoteException e) {Log.wtf(TAG, "Error calling adjustVolumeBy", e);}}case KeyEvent.ACTION_UP: {final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE| AudioManager.FLAG_FROM_KEY;try {mSessionBinder.adjustVolume(mContext.getPackageName(), mCbStub, true, 0, flags);} catch (RemoteException e) {Log.wtf(TAG, "Error calling adjustVolumeBy", e);}}}
}

/frameworks/base/services/core/java/com/android/server/media/MediaSessionRecord.java
通过ISessionController的AIDL方式调用到MediaSessionRecord中的adjustVolume().
通过SessionCb中的回调,调用mCb.onAdjustVolume()即MediaSession中的onAdjustVolume().

\frameworks\base\media\java\android\media\session\MediaSession.java

@Override
public void onAdjustVolume(String packageName, int pid, 

这篇关于Android Input输入系统之五:KeyEvent按键调节音量加减流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/733588

相关文章

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节

Nginx、Tomcat等项目部署问题以及解决流程

《Nginx、Tomcat等项目部署问题以及解决流程》本文总结了项目部署中常见的four类问题及其解决方法:Nginx未按预期显示结果、端口未开启、日志分析的重要性以及开发环境与生产环境运行结果不一致... 目录前言1. Nginx部署后未按预期显示结果1.1 查看Nginx的启动情况1.2 解决启动失败的

CentOS系统使用yum命令报错问题及解决

《CentOS系统使用yum命令报错问题及解决》文章主要讲述了在CentOS系统中使用yum命令时遇到的错误,并提供了个人解决方法,希望对大家有所帮助,并鼓励大家支持脚本之家... 目录Centos系统使用yum命令报错找到文件替换源文件为总结CentOS系统使用yum命令报错http://www.cppc

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica