Android不同音源型別的音量設定問題:
阿新 • • 發佈:2019-02-15
先上一張個人專案研發settings應用的一個功能,效果圖如下:
個人根據專案相關程式碼跟蹤到framework層時(framework層關鍵程式碼如下:)
@Override
public int adjustVolumeLevel(int volumeType, int level) {
if (null == mAudioManager) {
return -1;
}
boolean bMcuMute = false;
if (null == mSettingService) {
mSettingService = SettingService.getInstance();
}
if (null != mSettingService) {
try {
bMcuMute = mSettingService.isMcuMute();
} catch (RemoteException e) {
e.printStackTrace();
}
}
switch (volumeType) {
case VOLUME_TYPE_MUSIC:
case VOLUME_TYPE_NVGIS:
if (level >= 0 && masterMax() >= level) {
if (bMcuMute && 0 != level) {
setSystemMute(false);
}
mAudioManager.setStreamVolume(AudioManager.STREAM_GIS, level, 0);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, level, 0 );
saveAudioTypeVolumeLevel(AudioManager.STREAM_GIS, level);
saveAudioTypeVolumeLevel(AudioManager.STREAM_MUSIC, level);
}
break;
case VOLUME_TYPE_BTHFP:
if (level >= 0 && bthfpMax() >= level) {
mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, level, 0);
saveAudioTypeVolumeLevel(AudioManager.STREAM_BLUETOOTH_SCO, level);
}
break;
case VOLUME_TYPE_BKCAR:
if (level >= 0 && backcarMax() >= level) {
mAudioManager.setStreamVolume(AudioManager.STREAM_BACKCAR, level, 0);
saveAudioTypeVolumeLevel(AudioManager.STREAM_BACKCAR, level);
}
break;
case VOLUME_TYPE_xRING:
if (level >= 0 && ringMax() >= level) {
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, level, 0);
saveAudioTypeVolumeLevel(AudioManager.STREAM_RING, level);
}
break;
default:
break;
}
return 0;
}
發現Android實際上已經針對不同音源的不同音量設定提供了介面,其原始碼路徑為<個人使用的是Android4.2.2平臺程式碼>:path:\android4.2.2\frameworks\base\media\java\android\media\AudioService.java,部分關鍵程式碼如下:
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags) {
ensureValidStreamType(streamType);
VolumeStreamState streamState = mStreamStates[mStreamVolumeAlias[streamType]];
final int device = getDeviceForStream(streamType);
int oldIndex;
boolean force = false;
flags &= ~AudioManager.FLAG_FIXED_VOLUME;
if ((mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
((device & mFixedVolumeDevices) != 0)) {
flags |= AudioManager.FLAG_FIXED_VOLUME;
index = mStreamStates[streamType].getMaxIndex();
oldIndex = index;
} else {
// get last audible index if stream is muted, current index otherwise
oldIndex = streamState.getIndex(device,
(streamState.muteCount() != 0) /* lastAudible */);
index = rescaleIndex(index * 10, streamType, mStreamVolumeAlias[streamType]);
if (!checkSafeMediaVolume(mStreamVolumeAlias[streamType], index, device)) {
return;
}
if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
force = true;
}
// setting volume on master stream type also controls silent mode
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
(mStreamVolumeAlias[streamType] == getMasterStreamType())) {
int newRingerMode;
if (index == 0) {
newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT;
setStreamVolumeInt(mStreamVolumeAlias[streamType],
index,
device,
force,
true);
} else {
newRingerMode = AudioManager.RINGER_MODE_NORMAL;
setRingerMode(newRingerMode);
}
//setRingerMode(newRingerMode); 移動到else中,正對Ring = 0避免全部靜音
}
setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, false, true);
// get last audible index if stream is muted, current index otherwise
index = mStreamStates[streamType].getIndex(device,
(mStreamStates[streamType].muteCount() != 0) /* lastAudible */);
}
sendVolumeUpdate(streamType, oldIndex, index, flags);
}
這邊實際上是AudioManager呼叫了AudioService的相關方法,而AudioService又呼叫了本地jni庫的方法。
上層使用方式:
我們直接通過context取get一個AudioManager管理者,然後通過設定不同音訊通道即可,程式碼如下:
mAudioManager.setStreamVolume(AudioManager.STREAM_GIS, level, 0);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, level, 0);
mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, level, 0);
mAudioManager.setStreamVolume(AudioManager.STREAM_BACKCAR, level, 0);
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, level, 0);