今天跟了一下Android系统按键静音的流程,Android实现了在系统层面静音。输出给底层的音量为0。
按键使用注入按键方式实现,静音按键值:
public static final int KEYCODE_VOLUME_MUTE = 164;
注入方式:
KeyEvent k = new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_VOLUME_MUTE);
InputManager.getInstance().injectInputEvent(key, 0);
或者:
simulateKey(KeyEvent.KEYCODE_VOLUME_MUTE);
public static void simulateKey(final int KeyCode) {
new Thread() {
@Override
public void run() {
try {
Instrumentation inst = new Instrumentation();
inst.sendKeyDownUpSync(KeyCode);
} catch (Exception e) {
Log.e("hello", e.toString());
}
}
}.start();
}
调用流程:
DecorView.java --> PhoneWindow.java --> MediaSessionService.java
窗口监听Key消息的过程省略过,在Input输入系统中已经分析过。
\frameworks\base\services\core\java\com\android\server\media\MediaSessionService.java
dispatchVolumeKeyEvent()
dispatchVolumeKeyEventLocked()
\frameworks\base\services\core\java\com\android\server\audio\AudioService.java
adjustSuggestedStreamVolume()
private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
String callingPackage, String caller, int uid) {
//省略一部分代码
//...
// mute为true
final boolean isMute = isMuteAdjust(direction);
ensureValidStreamType(streamType);
final int resolvedStream = mStreamVolumeAlias[streamType];
// Play sounds on STREAM_RING only.
if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
resolvedStream != AudioSystem.STREAM_RING) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}
// For notifications/ring, show the ui before making any adjustments
// Don't suppress mute/unmute requests
if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {
direction = 0;
flags &= ~AudioManager.FLAG_PLAY_SOUND;
flags &= ~AudioManager.FLAG_VIBRATE;
if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
}
adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
}
protected void adjustStreamVolume(int streamType, int direction, int flags,
String callingPackage, String caller, int uid) {
//省略一部分代码
//...
//省略一部分代码
//...
if (isMuteAdjust) {
boolean state;
if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
state = !streamState.mIsMuted;
} else {
state = direction == AudioManager.ADJUST_MUTE;
}
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
setSystemAudioMute(state