android音量调节可以参考下面的链接:
1、音量调节流程分析
android音频系统(4):AudioService之音量管理_renshuguo123723的博客-CSDN博客_audioservice
Android java层音频相关的分析与理解(二)音量控制相关_u012440406的专栏-CSDN博客
2、AudioManager里面setStreamVolume调用流程
Android Audio:setStreamVolume()音量调节过程_Good Good Study Day Day Up!!!-CSDN博客_android setstreamvolume
3、流程图
Android Audio(八)—— Volume_tudouhuashengmi的博客-CSDN博客
4、AudioTrack的音量
android 音量调节_renshuguo123723的博客-CSDN博客
5、音量保存到数据库
Android Audio音量保存_xlnaan的博客-CSDN博客_android volume_music_hdmi
注意点:
(1)streamState:
所以AudioService提供了VolumeStreamState类,为每一种流类型都分配了一个VolumeStreamState对象,VolumeStreamState保存了一个流类型所有音量相关的信息。并且以流类型的值为索引,将它保存在一个名为mStreamStates的数组中。
比如:
a、 VolumeStreamState streamState = mStreamStates[streamTypeAlias];
final int device = getDeviceForStream(streamTypeAlias);
int aliasIndex = streamState.getIndex(device);
b、int oldIndex = mStreamStates[streamType].getIndex(device);
(2)adjustIndex
public boolean adjustIndex(int deltaIndex, int device, String caller) {
//将现有的音量值加上变化量,然后调用setIndex进行设置
return setIndex(getIndex(device) + deltaIndex, device, caller);
}
public boolean setIndex(int index, int device, String caller) {
boolean changed = false;
int oldIndex;
synchronized (VolumeStreamState.class) {
oldIndex = getIndex(device);
index = getValidIndex(index);
synchronized (mCameraSoundForced) {
if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
index = mIndexMax;
}
}
//保存设置的音量值,使用了Map
mIndexMap.put(device, index);
changed = oldIndex != index;
//同时设置所有映射到当前流类型的其他流的音量
final boolean currentDevice = (device == getDeviceForStream(mStreamType));
final int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
final VolumeStreamState aliasStreamState = mStreamStates[streamType];
if (streamType != mStreamType &&
mStreamVolumeAlias[streamType] == mStreamType &&
(changed || !aliasStreamState.hasIndexForDevice(device))) {
final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
aliasStreamState.setIndex(scaledIndex, device, caller);
if (currentDevice) {
aliasStreamState.setIndex(scaledIndex,
getDeviceForStream(streamType), caller);
}
}
}
}
if (changed) {
//加5是为了四舍五入,除10,因为10的整数容易操作
oldIndex = (oldIndex + 5) / 10;
index = (index + 5) / 10;
//发送广播
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
mStreamVolumeAlias[mStreamType]);
sendBroadcastToAll(mVolumeChanged);
}
return changed;
}
这个函数做的事情是:
1》首先是保存设置的音量值到hashMap表里,音量值与设备相关联,。对同一种流类型来说,在不同的音频设备下将会有不同的音量值;
2》再就是对流映射的处理。既然A→B,那么在设置B的音量的同时要改变A的音量;
可以看出,VolumeStreamState.adjustIndex()除了更新自己所保存的音量值外,没有做其他的事情;
(3)将音量保存在数据库里面。
private void persistVolume(VolumeStreamState streamState, int device) {
if (mUseFixedVolume) {
return;
}
if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
return;
}
if (streamState.hasValidSettingsName()) {
//将音量值写进SettingProvider
System.putIntForUser(mContentResolver,
streamState.getSettingNameForDevice(device),
(streamState.getIndex(device) + 5)/ 10,
UserHandle.USER_CURRENT);
}
}



