Android.media.AudioManager中包含了对android.media.AudioService的跨进程AIDL调用封装。

源码里面 framework/base/policy/PhoneWindowManager.java里面的interceptKeyBeforeDispatching和interceptKeyBeforeQueueing两个方法控制。(前者处理home,menu,search三个,后者处理,volumn_up,volumn_down,power等等键)
正常处理过程:
1.调整音量是通过AudioManager间接调用AudioService.adjustStreamVolume方法来完成逻辑处理;
2.AudioService调用VolumePanel画出音量调整界面,并发送音量变动广播消息,
3.StatusBarPolicy,接收广播消息判断是否在状态栏显示静音或振动图标。

问题点:
1.AudioManager如何接收音量调整事件?

答:PhoneWindowManager.interceptKeyBeforeQueueing处理的
WindowManagerService循环读取下面的消息再做分发到窗口接收,在消息分发前会有一个类做消息过滤处理,就是PhoneWindowManager.interceptKeyBeforeQueueing;
比如音量调整、Home键都在这个类里面做特殊处理,详细内容后面会在其它该当再补充


2.谁负责处理音量显示的?
答:AudioManager调用AudioService来显示的。事件触发在AudioManager,代码的执行实现在AudioService中。状态栏是SystemUI的APK包StatusBarPolicy中接收广播消息来处理的。

源码位置:
/frameworks/base/media/java/android/media/AudioManager.java
/frameworks/base/media/java/android/media/AudioService.java
/framework/base/core/java/Android/view/VolumePanel.java
/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java

AudioService.adjustStreamVolume方法完成以下三个功能:
一.音量调整
音量调整分为两步:先查看模式(Ring mode)是否需要调整? 然后再调用调整音量。
调整模式通过调用checkForRingerModeChange(oldIndex, direction);实现,
调整音量通过调用streamState.adjustIndex(direction)实现。

二.向用户显示调整音量的界面
调用mVolumePanel.postVolumeChanged(streamType, flags);发送音量变动消息,向用户显示改变结果。
调用过程VolumePanel.postVolumeChanged->VolumePanel.onVolumeChanged->VolumePanel.onShowVolumeChanged->mToast

三.广播音量有变动的系统事件
AudioService.sendVolumeUpdate(streamType);广播音量有改变的系统事件,状态栏根据这广播事件显示静音或振动图标

状态栏的静音或振动图标显示过程
StatusBarPolicy主要负责在静音模式(silent mode)和振动模式(vibrate mode)下在状态栏(status bar)的右方显示一个代表相应意义的图标。
一.系统启动后,StatusBarPolicy会注册一个Receiver,它可以接收很多种广播,其中就有AudioService在完成每一次的模式和音量更新时发出的两个广播事件

private BroadcastReceiver mIntentReceiver = new BroadcastReceiver()//新一个广播接收类‘
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);//添加接收的广播消息

filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);//注册一个Receiver,接收广播消息

二.接收广播,并调用updateVolume调整状态栏显示
else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
updateVolume();//调用音量状态栏显示
}


更多相关文章

  1. 【Android】Android(安卓)Input
  2. [Android]滑动冲突之内部拦截法
  3. Android实现点击事件的三种方法
  4. android eventBus 的简单使用(一)
  5. Android培训班(14)
  6. Android(安卓)Input Framework(三)---InputReader&InputDispatch
  7. Android(安卓)DataBinding 双向数据绑定、事件绑定、使用类方法
  8. android 比较有用的方法总结
  9. Android接收RabbitMQ消息。

随机推荐

  1. Android(安卓)在界面中显示以及输入文本
  2. android udp通信
  3. 【android】关于退出时关闭“后台”显示
  4. 详解 Android(安卓)的 Activity 组件
  5. Ubuntu 系统上编译Android(安卓)系统
  6. android TextView xml中设置最大行数
  7. android 开发包的离线安装方式
  8. Android(安卓)EditText的inputType属性值
  9. android:windowSoftInputMode属性使用
  10. Android(安卓)—— 第一次安装 Android(