如何修改frameworks实现音量统一调节
2016-07-07 12:09
597 查看
修改音量最大值和默认音量
拦截音量键分发
在其他应用中添加广播接收者处理音量加减广播
打开主音量调节功能设置音量加减步长
测试
源码为MTK的MT8735平台源码,android 5
MAX_STREAM_VOLUME为最大值,DEFAULT_STREAM_VOLUME为默认值
为了统一调节音量,把默认音量和最大音量,所有STREAM都保持一致。
如果采用Master音量调节,就不需要设置了,因为Master音量调节最大都是100
方法名:public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags)
作用:在分发之前拦截按键事件。是否分发给应用自己处理,根据返回值:return -1 不返回,自己处理了。return 0 返回给应用自己处理
拦截音量键
音量键码:KeyEvent.KEYCODE_VOLUME_DOWN KeyEvent.KEYCODE_VOLUME_UP
我们需要音量键按下后,发出按下广播。(来电铃声响起时,音量键起到静音作用,所以来电话的时候不拦截音量键,让系统处理)
注册广播:
将config_useMasterVolume设置为true。
约86行,第二个item根据调试设置步长。默认是5, 这里改成1。根据测试,调节音量时,从最小到最大,需要按+键16下左右
当用户调用adjustStreamVolume的时候,mUseMasterVolume是上面config_useMasterVolume的值。
由Master调节音量,所有音量最大为100,发出音量调节广播为:
“android.media.MASTER_VOLUME_CHANGED_ACTION”
而普通的音量调节,最大音量根据AudioService.java中MAX_STREAM_VOLUME定义的,默认音量DEFAULT_STREAM_VOLUME
广播为:“android.media.VOLUME_CHANGED_ACTION”
拦截音量键分发
在其他应用中添加广播接收者处理音量加减广播
打开主音量调节功能设置音量加减步长
测试
源码为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 测试
写一个测试程序测试相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories