1. 程式人生 > >Android不同音源型別的音量設定問題:

Android不同音源型別的音量設定問題:

先上一張個人專案研發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);