Android 设置音量默认值

        在车机 Audio 开发中,设置音量默认值是必要的,很多时候也需要定制化开发。还有很多场景需要设置音量的最大值和最小值问题,例如通话模式通常是禁止静音的,耳机模式调整到较大音量时开机后会恢复一个最大默认值等问题。而且通常情况下不通车型的默认值可能会不同,这篇文章就来看一下如何在一套代码中维护不同车型的默认音量。

一、系统默认音量

1、默认音量

源码位置:frameworks/base/media/java/android/media/AudioSystem.java

public static int[] DEFAULT_STREAM_VOLUME = new int[] {
    4,  // STREAM_VOICE_CALL
    7,  // STREAM_SYSTEM
    5,  // STREAM_RING
    5, // STREAM_MUSIC
    6,  // STREAM_ALARM
    5,  // STREAM_NOTIFICATION
    7,  // STREAM_BLUETOOTH_SCO
    7,  // STREAM_SYSTEM_ENFORCED
    5, // STREAM_DTMF
    5, // STREAM_TTS
    5, // STREAM_ACCESSIBILITY
    5, // STREAM_ASSISTANT
};

2、 最大/小音量

源码位置frameworks/base/services/core/java/com/android/server/audio/AudioService.java

/** 音频流的最大音量索引值 */
protected static int[] MAX_STREAM_VOLUME = new int[] {
    5,  // STREAM_VOICE_CALL
    7,  // STREAM_SYSTEM
    7,  // STREAM_RING
    15, // STREAM_MUSIC
    7,  // STREAM_ALARM
    7,  // STREAM_NOTIFICATION
    15, // STREAM_BLUETOOTH_SCO
    7,  // STREAM_SYSTEM_ENFORCED
    15, // STREAM_DTMF
    15, // STREAM_TTS
    15, // STREAM_ACCESSIBILITY
    15  // STREAM_ASSISTANT
};

/** 音频流的最小音量索引值 */
protected static int[] MIN_STREAM_VOLUME = new int[] {
    1,  // STREAM_VOICE_CALL
    0,  // STREAM_SYSTEM
    0,  // STREAM_RING
    0,  // STREAM_MUSIC
    1,  // STREAM_ALARM
    0,  // STREAM_NOTIFICATION
    0,  // STREAM_BLUETOOTH_SCO
    0,  // STREAM_SYSTEM_ENFORCED
    0,  // STREAM_DTMF
    0,  // STREAM_TTS
    1,  // STREAM_ACCESSIBILITY
    0   // STREAM_ASSISTANT
};

3、默认值修改

        虽然我们找到了默认值的定义位置,但是声音属性默认值最好不要在这里进行修改,否则可能修改无效。因为这两种音量属性被定义之后,还会在 AudioService 的构造方法中进行初始化。在此期间,之前定义的音量值会被覆盖掉。

public AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer) {
    ……
    int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
    if (maxCallVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
    }

    int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
    if (defaultCallVolume != -1 &&
                defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
                defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
    } else {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
                    (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
    }

    int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
    if (maxMusicVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
    }

    int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
    if (defaultMusicVolume != -1 &&
                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
                defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
    } else {
        if (isPlatformTelevision()) {
            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
        } else {
            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
        }
    }

    int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
    if (maxAlarmVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
    }

    int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
    if (defaultAlarmVolume != -1 &&
                defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
    } else {
        // 默认值是7分中的6分(默认最大值),因此相应地缩放。
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
                        6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
    }
    
    int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
    if (maxSystemVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
    }

    int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
    if (defaultSystemVolume != -1 && defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
    } else {
        // 默认是使用maximum。
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
    }
    ……
}

        以多媒体默认音量为例,我们可以看到,它最终的设置结果是最大音量的三分之一,即 15/3=5 格音量。 

int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
if (defaultMusicVolume != -1 &&
                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
                defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
    AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
} else {
    if (isPlatformTelevision()) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
    } else {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
    }
}

        所以,它的修改方式应该是这样的: 

//多媒体默认音量修改为10格
int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", 10);

        其实这里是系统一用来记录用户设置音量的,首先取出用户设置的音量,如果取出的值在最大值和最小值之间,直接使用该音量。否则设置最大音量的三分之一为默认音量。

一、自定义音量值

        对于车机开发来说,为了方便维护我们也可以定义一套自定义音量值的 xml 文件。

1、配置默认值

        通常情况下,需要在上面的文件中添加相关默认值属性。

config.xml

源码位置:/packages/services/Car/service/res/values/config.xml

<integer name="mediaMaxVolume">20</integer>
<integer name="mediaMinVolume">5</integer>
<integer name="alarmMaxVolume">20</integer>
<integer name="alarmMinVolume">5</integer>

        这里设置了多媒体的最大音量为 20,最小音量为 10。设置了闹钟的最小音量为 5。

2、初始化数据

CarAudioService

源码位置:/packages/services/Car/service/src/com/android/car/CarAudioService.java

public class CarAudioService extends ICarAudio.Stub implements CarServiceBase, PowerEventProcessingHandler {
    ……
    private static final String MEDIA_MIN_VOLUME  = "vendor.media.min.volume";
    private static final String MEDIA_MAX_VOLUME  = "vendor.media.max.volume";
    private static final String ALARM_MIN_VOLUME  = "vendor.alarm.min.volume";
    private static final String ALARM_MAX_VOLUME  = "vendor.alarm.max.volume";
	
    private int mMediaMinVolume;
    private int mMediaMaxVolume;
    private int mAlarmMinVolume;
    private int mAlarmMaxVolume;

    @Override
    public void init() {
        ……
        synchronized (mImplLock) {
            ……
            Resources res = mContext.getResources();
            mMediaMinVolume = res.getInteger(R.integer.mediaMinVolume);
            mMediaMaxVolume = res.getInteger(R.integer.mediaMaxVolume);
            mAlarmMinVolume = res.getInteger(R.integer.alarmMinVolume);
            mAlarmMaxVolume = res.getInteger(R.integer.alarmMaxVolume);
            SystemProperties.set(MEDIA_MIN_VOLUME, String.valueOf(mMediaMinVolume));
            SystemProperties.set(MEDIA_MAX_VOLUME, String.valueOf(mMediaMaxVolume));
            SystemProperties.set(ALARM_MIN_VOLUME, String.valueOf(mAlarmMinVolume));
            SystemProperties.set(ALARM_MAX_VOLUME, String.valueOf(mAlarmMaxVolume));
            ……
        }
        ……
    }
    ……
}

        这里就是取出 xml 中的数据,存储到系统变量中,我们这里看一下存储方式。

SystemProperties

源码位置:/frameworks/base/core/java/android/os/SystemProperties.java

/**
 * 提供对系统属性存储的访问权限。系统属性存储包含字符串键值对列表。
 * 该类仅用于本地的系统属性。
 */
public class SystemProperties {
    private static final boolean TRACK_KEY_ACCESS = false;

    public static String get(@NonNull String key) {
        if (TRACK_KEY_ACCESS) onKeyAccess(key);
        return native_get(key);
    }

    public static String get(@NonNull String key, @Nullable String def) {
        if (TRACK_KEY_ACCESS) onKeyAccess(key);
        return native_get(key, def);
    }
}

        可以看到这就相当于一个用于存储系统属性的工具类。

3、获取数据

        在上面的 AudioService 中可以使用这里存储的数据进行赋值,这样就使用了自定义数据。

private static final String MEDIA_MIN_VOLUME  = "vendor.media.min.volume";
private static final String MEDIA_MAX_VOLUME  = "vendor.media.max.volume";
private static final String ALARM_MIN_VOLUME  = "vendor.alarm.min.volume";
private static final String ALARM_MAX_VOLUME  = "vendor.alarm.max.volume";
	
private int mMediaMinVolume;
private int mMediaMaxVolume;
private int mAlarmMinVolume;
private int mAlarmMaxVolume;

mMediaMinVolume = SystemProperties.get(MEDIA_MIN_VOLUME);
mMediaMaxVolume = SystemProperties.get(MEDIA_MAX_VOLUME);
mAlarmMinVolume = SystemProperties.get(ALARM_MIN_VOLUME);
mAlarmMaxVolume = SystemProperties.get(ALARM_MAX_VOLUME);

4、定制设置

        如果只有一组设置,直接使用上面的代码就可以了。但是如果当前有多个车型,且对音量的边界值设置还不一样,这就需要定制化设置了。例如我们有 xx01 和 xx02 两个车型,他们的定制化文件存放在 /device/xiaoxu/xx01 和 /device/xiaoxu/xx02 下。这里配置默认值需要覆盖上面的配置信息,所以需要添加 overlay 路径。

xx01

源码位置:/device/xiaoxu/xx01/overlay/packages/services/Car/service/res/values/config.xml

<integer name="mediaMaxVolume">18</integer>
<integer name="mediaMinVolume">3</integer>
<integer name="alarmMaxVolume">18</integer>
<integer name="alarmMinVolume">3</integer>

 xx02

源码位置:/device/xiaoxu/xx02/overlay/packages/services/Car/service/res/values/config.xml

<integer name="mediaMaxVolume">22</integer>
<integer name="mediaMinVolume">7</integer>
<integer name="alarmMaxVolume">22</integer>
<integer name="alarmMinVolume">7</integer>

        这样该文件就会覆盖上面的设置,而对于数值的初始化和获取方式与上面的相同,这里就不再重复添加。

猜你喜欢

转载自blog.csdn.net/c19344881x/article/details/134924790