天天看点

【Android系统源码修改】如何修改frameworks实现音量统一调节

文章目录

源码为MTK的MT8735平台源码,android 5

###1 修改音量最大值和默认音量

源码位置:frameworks/base/media/java/android/media/AudioService.java 约266行

MAX_STREAM_VOLUME为最大值,DEFAULT_STREAM_VOLUME为默认值

为了统一调节音量,把默认音量和最大音量,所有STREAM都保持一致。

如果采用Master音量调节,就不需要设置了,因为Master音量调节最大都是100

/** @hide Maximum volume index values for audio streams */
   /// M: Modify the max stream volume @{
    private static final int[] MAX_STREAM_VOLUME = new int[] {
        20,  // STREAM_VOICE_CALL
        20,  // STREAM_SYSTEM
        20,  // STREAM_RING
        20,  // STREAM_MUSIC
        20,  // STREAM_ALARM
        20,  // STREAM_NOTIFICATION
        20,  // STREAM_BLUETOOTH_SCO
        20,  // STREAM_SYSTEM_ENFORCED
        20,  // STREAM_DTMF
        20,  // STREAM_TTS
    };
    /// @}

    /**
     * @hide Default volume index values for audio streams
     * M: modify the default stream volume @{
     */
    public static int[] DEFAULT_STREAM_VOLUME = new int[] {
        9,  // STREAM_VOICE_CALL
        9,  // STREAM_SYSTEM
        9,  // STREAM_RING
        9,  // STREAM_MUSIC
        9,  // STREAM_ALARM
        9,  // STREAM_NOTIFICATION
        9,  // STREAM_BLUETOOTH_SCO
        9,  // STREAM_SYSTEM_ENFORCED
        9,  // STREAM_DTMF
        9,  // STREAM_TTS
    };
    /** @ */
           

###2 拦截音量键分发

源码位置:frameworks/base/policy/src/com/android/internel/policy/impl/PhoneWindowManager.java 约2607行

方法名:public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags)

作用:在分发之前拦截按键事件。是否分发给应用自己处理,根据返回值:return -1 不返回,自己处理了。return 0 返回给应用自己处理

拦截音量键

音量键码:KeyEvent.KEYCODE_VOLUME_DOWN KeyEvent.KEYCODE_VOLUME_UP

if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
     // TODO: 这里添加你需要音量键按下后做什么事
     return -1;
}
           

我们需要音量键按下后,发出按下广播。(来电铃声响起时,音量键起到静音作用,所以来电话的时候不拦截音量键,让系统处理)

Intent intent = new Intent();
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
    TelecomManager telecomManager = getTelecommService();
    if (telecomManager == null || !(telecomManager.isRinging() || telecomManager.isInCall())) {
        if (down) {
            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                intent.setAction("xxx.ACTION_VOLUME_DOWN");
                mContext.sendBroadcast(intent);
            } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
                intent.setAction("xxx.ACTION_VOLUME_UP");
                mContext.sendBroadcast(intent);
            }
            return -1;
        }
    }            
}

           

###3 在其他应用中添加广播接收者处理音量加减广播

public class VolumeEventReceiver extends BroadcastReceiver {
    Context mContext;
    AudioManager manager;
    int[] stream = {
            AudioManager.STREAM_RING,
            AudioManager.STREAM_ALARM,
            AudioManager.STREAM_NOTIFICATION,
            AudioManager.STREAM_DTMF,
            AudioManager.STREAM_VOICE_CALL,
            AudioManager.STREAM_SYSTEM,
            AudioManager.STREAM_MUSIC,
    };

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            mContext = context;
            manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

            String action = intent.getAction();
            if ("xxx.ACTION_VOLUME_DOWN".equals(action)) {
                controlVolume(AudioManager.ADJUST_LOWER);

            } else if ("xxx.ACTION_VOLUME_UP".equals(action)) {
                controlVolume(AudioManager.ADJUST_RAISE);
            }

        } catch (Exception e) {
            Log.i("VolumeEvent", "*** Exception: " + e.getMessage());
        }
    }

    void controlVolume(int direction) {
        for (int i = 0; i < stream.length - 1; i++) {
            manager.adjustStreamVolume(stream[i], direction, 0);
        }
        // 显示媒体音量调节的图标,其他音量图标不显示
        manager.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction,
                AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND);
    }

}
           

注册广播:

<receiver android:name=".VolumeEventReceiver" 
        android:exported="false">
      <intent-filter>
          <action android:name="xxx.ACTION_VOLUME_DOWN" />
          <action android:name="xxx.ACTION_VOLUME_UP" />
      </intent-filter>
  </receiver>

           

###4 打开主音量调节功能,设置音量加减步长

源码位置:frameworks/base/core/res/res/values/config.xml 约71行

将config_useMasterVolume设置为true。

<!-- Flag indicating that the media framework should allow changing
    master volume stream and nothing else . -->
<bool name="config_useMasterVolume">true</bool>
           

约86行,第二个item根据调试设置步长。默认是5, 这里改成1。根据测试,调节音量时,从最小到最大,需要按+键16下左右

<integer-array name="config_masterVolumeRamp">
   <item>0</item>  <item>1</item>  <!-- default: always increase volume by 5% -->
</integer-array>
           

当用户调用adjustStreamVolume的时候,mUseMasterVolume是上面config_useMasterVolume的值。

public void adjustStreamVolume(int streamType, int direction, int flags) {
    IAudioService service = getService();
    Log.d(TAG, "adjustStreamVolume: StreamType = " + streamType + ", direction = " + direction);
    try {
        if (mUseMasterVolume) {
            service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
        } else {
            service.adjustStreamVolume(streamType, direction, flags,
                    mContext.getOpPackageName());
        }
    } catch (RemoteException e) {
        Log.e(TAG, "Dead object in adjustStreamVolume", e);
    }
}
           

由Master调节音量,所有音量最大为100,发出音量调节广播为:

"android.media.MASTER_VOLUME_CHANGED_ACTION"

而普通的音量调节,最大音量根据AudioService.java中MAX_STREAM_VOLUME定义的,默认音量DEFAULT_STREAM_VOLUME

广播为:"android.media.VOLUME_CHANGED_ACTION"

###5 测试

写一个测试程序测试

【Android系统源码修改】如何修改frameworks实现音量统一调节
【Android系统源码修改】如何修改frameworks实现音量统一调节
【Android系统源码修改】如何修改frameworks实现音量统一调节
【Android系统源码修改】如何修改frameworks实现音量统一调节