博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何更精细地调整安卓系统的音量级别?
阅读量:4090 次
发布时间:2019-05-25

本文共 2852 字,大约阅读时间需要 9 分钟。

原生安卓系统只能调出15级音量,而市面上很多已上传的音量APP也只能调整这15级音量,这样的调整方式,级别粗糙,不够贴心。

而许多大厂音乐类APP都只支持这十几级系统音量,不支持APP内部(MediaPlayer)的音量调整。

可以用全局均衡器来进一步微调音量,相当于为15个音量级别的每一级额外增加数千个微调等级。

构造全局均衡器(应用于系统级别)与构造一般均衡器(APP内部有效)一样,无需 context,区别是为全局均衡器传入的 session id 为零:

mEqualizer = new Equalizer(999, 0);

全局均衡器被官方标注为不推荐,甚至废弃,但没有替代方案,也未被彻底舍弃,在较新的设备商仍然能够使用。

全局均衡器会因被其他APP的一般均衡器干扰而失效,两个构造参数(优先级、session id)全部被无视了。

安卓的声音系统较弱,某些设备在调节、切换时会有爆音现象(完全静音了但是偶然会很响地噗一下刺耳朵)。

全局均衡器有着如此的缺陷,不是很健壮,但仍然有其使用武之地。

Precise volume 这款应用也支持全局均衡器,不过界面复杂,调节费手,一共五个推杆,需要一个个推杆推过去地调。

所以,我决定在我的浏览器项目中加入调节系统音量的功能,只用一个进度条就可以控制全部。

稍后,我有将两三年前为播放器项目写的、可以用一次滑动触摸修改所有推杆的均衡器界面搬到了这个浏览器项目上面。


抛开界面,设置全局均衡器的代码如下:

Utils.java

public static int mGlobalEqShift = Integer.MAX_VALUE;	public static Equalizer mEqualizer;	public static int[] bandLevels;		public static void setSystemEqualizer(Options opt, boolean prepareUI) {		boolean adjust = opt.getAdjustSystemVolume();		Equalizer mEqualizer = Utils.mEqualizer;		if (adjust || prepareUI) {			if (mEqualizer==null) {				try {					Utils.mEqualizer = mEqualizer = new Equalizer(999, 0);				} catch (Exception ignored) { }				if (bandLevels==null) {					bandLevels = new int[mEqualizer.getNumberOfBands()];				}				if (mGlobalEqShift==Integer.MAX_VALUE) {					opt.getBandLevels(bandLevels);					mGlobalEqShift = opt.getGlobalEqShift();				}			}			if (!prepareUI && mEqualizer!=null) {				int min = mEqualizer.getBandLevelRange()[0];				int max = mEqualizer.getBandLevelRange()[1];								float shiftGlobal = (mGlobalEqShift-5000)/10000.f*(max-min);								int count = bandLevels.length;				for (int i = 0; i < count; i++) {					int modified = (int) Math.max(min, Math.min(max, bandLevels[i]+shiftGlobal));					//CMN.Log("modified::", modified, i);					mEqualizer.setBandLevel((short) i, (short) modified);				}				mEqualizer.setEnabled(true);			}		} else if (mEqualizer!=null) {			mEqualizer.setEnabled(false);		}	}

opt 是我的设置类。其中处理五个推杆数值、整体偏移数值的保存,也很简单:

Options.java

public final SharedPreferences defaultReader;	public int getGlobalEqShift() {		return defaultReader.getInt("eqSft", 5000);	}		public void putGlobalEqShift(int val) {		defaultReader.edit().putInt("eqSft", val).apply();	}		public void getBandLevels(int[] levels) {		String[] bands = defaultReader.getString("bands", "").split(";");		for (int i = 0, len=Math.min(levels.length, bands.length); i < len; i++) {			levels[i] = IU.parsint(bands[i]);		}	}		public void putBandLevels(int[] levels) {		StringBuilder str= new StringBuilder(32);		for (int i = 0, len=levels.length; i < len; i++) {			str.append(levels[i]);			if (i

或许需要权限:

这些写起来很容易,不过界面就不简单了。要为五个推杆写界面,需要用到垂直进度条。若要用一次滑动手势修改全部推杆,就需要更多的技巧。


有关均衡器的这些种种我已在几年前玩过了,当年还整合了vlc、exoplayer、mediaplayer、ijkplayer到一个App内,低版本安卓设备自带的解码器不全,可以切换VLC播放组件,支持的格式更全。切换至 exoplayer 或者 ijkplayer,则功能更多、切换视频速度更快。而这些播放器组件均支持均衡器,其中vlc支持更多的均衡器推杆,记得好像是二十个。

时过境迁,现在看看搬过来的效果也还不错:

好用的均衡器控制面板

控制系统全局音量

转载地址:http://nmbii.baihongyu.com/

你可能感兴趣的文章
如何用好碎片化时间,让思维更有效率?
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Java8 HashMap集合解析
查看>>
自定义 select 下拉框 多选插件
查看>>
fastcgi_param 详解
查看>>
搞定Java面试中的数据结构问题
查看>>
React Native(一):搭建开发环境、出Hello World
查看>>
Winform多线程
查看>>
Spring AOP + Redis + 注解实现redis 分布式锁
查看>>
poj 1976 A Mini Locomotive (dp 二维01背包)
查看>>
《计算机网络》第五章 运输层 ——TCP和UDP 可靠传输原理 TCP流量控制 拥塞控制 连接管理
查看>>
《PostgreSQL技术内幕:查询优化深度探索》养成记
查看>>
剑指_复杂链表的复制
查看>>
FTP 常见问题
查看>>
shell 快捷键
查看>>
MODULE_DEVICE_TABLE的理解
查看>>
build/envsetup.sh 简介
查看>>
编译Android4.0源码时常见错误及解决办法
查看>>
Android 源码编译make的错误处理
查看>>