首先简单介绍下预备知识:
1.Android的audio流的类型有以下12种:
/* The audio stream for phone calls */
public static final int STREAM_VOICE_CALL = 0;//通话连接时的音频流(通话声)
/* The audio stream for system sounds */
public static final int STREAM_SYSTEM = 1;//系统音频流
/* The audio stream for the phone ring and message alerts */
public static final int STREAM_RING = 2;//来电铃声
/* The audio stream for music playback */
public static final int STREAM_MUSIC = 3;//媒体音频流
/* The audio stream for alarms */
public static final int STREAM_ALARM = 4;//闹钟音频流
/* The audio stream for notifications */
public static final int STREAM_NOTIFICATION = 5;//通知音频流
/* @hide The audio stream for phone calls when connected on bluetooth */
public static final int STREAM_BLUETOOTH_SCO = 6;//从注释上看时使用蓝牙耳机通话的音频流
/* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
public static final int STREAM_SYSTEM_ENFORCED = 7;//一些国家强制使用的音频流??不太明白
/* @hide The audio stream for DTMF tones */
public static final int STREAM_DTMF = 8;//DTMF音频流
/* @hide The audio stream for text to speech (TTS) */
public static final int STREAM_TTS = 9;//TTS: Text to Speech:文件到语言的音频流,即机器说话
/* @hide The audio stream for Fm */
public static final int STREAM_FM = 10;//FM的音频流
/* @hide The audio stream for MATV */
public static final int STREAM_MATV = 11;//TV的音频流
每种音频流所规定的最大值:
/** @hide Maximum volume index values for audio streams */
private int[] MAX_STREAM_VOLUME = new int[] {
6, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
7, // STREAM_RING
12, // STREAM_MUSIC
7, // STREAM_ALARM
7, // STREAM_NOTIFICATION
15, // STREAM_BLUETOOTH_SCO
7, // STREAM_SYSTEM_ENFORCED
15, // STREAM_DTMF
15, // STREAM_TTS
13, //STREAM_FM
13 //stream_MATV
};
2.所有的按键事件都是touch事件,这部分我会另外开篇博文介绍。
开始本文正文,Anndroid系统中所有View带有按键音,用户可以通过Settings>Sound>勾选Audible Selection即可开启按键音。但是有个奇怪的地方:此按键音是与媒体音量(即STREAM_MUSIC)绑定的,难道按键音的STREAM TYPE就是STREAM_MUSIC吗?我们从代码中寻找一下。
首先所有的View点击的时候都有按键音,我们从View.java的点击事件找起,在view的响应的onTouchEvent()方法中有如下代码:
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
boolean prepressed = (mPrivateFlags & PREPRESSED) != 0;
if ((mPrivateFlags & PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
// touch mode.
boolean focusTaken = false;
if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
focusTaken = requestFocus();
}
if (!mHa