34-Android之耳机音量加大时警告提示框问题

Android4.4

展锐SC9820E平台,在进行GCF测试时,提出耳机警语问题。

我们在使用手机时,插入耳机,然后加大音量至安全音量时,会出现一个警告提示框,点击确定(或连续多次按音量+按键),才会继续增大音量。

而根据规范要求,在超过显示警告提示框的安全音量后, 如果播放音乐等超过20个小时,音量会自动回退到显示警告提示的安全音量。如果继续加大音量,又会出现警告提示框。

而GCF测试出现的问题是,超过20个小时后,音量没有回退安全音量。通过了解GCF测试时, 是通过播放FM进行测试的,通过对AudioService进行查看后,发现AudioService中展锐没有对AudioSystem.STREAM_FM(展锐添加的音频流类型)进行安全音量处理,因此需要自己添加,可以通过对比AudioSystem.STREAM_MUSIC进行添加。

frameworks/base/media/java/android/media/AudioService.java/** @see AudioManager#adjustStreamVolume(int, int, int) */public void adjustStreamVolume(int streamType, int direction, int flags,String callingPackage) {// ...省略// 进行安全音量检查if ((direction == AudioManager.ADJUST_RAISE) &&!checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex);mVolumePanel.postDisplaySafeVolumeWarning(flags); // 显示警告提示框} else if (streamState.adjustIndex(direction * step, device)) {// ... 省略int index = mStreamStates[streamType].getIndex(device);sendVolumeUpdate(streamType, oldIndex, index, flags);}// 检查安全音量private boolean checkSafeMediaVolume(int streamType, int index, int device) {synchronized (mSafeMediaVolumeState) {if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&((mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) || // 此处添加对AudioSystem.STREAM_FM的判断(mStreamVolumeAlias[streamType] == AudioSystem.STREAM_FM)) &&((device & mSafeMediaVolumeDevices) != 0) &&(index > mSafeMediaVolumeIndex)) {return false;}return true;}}

当点击警告提示框的确定或者继续加大音量,则执行AudioService的以下方法:

    private final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;private final int SAFE_MEDIA_VOLUME_DISABLED = 1;private final int SAFE_MEDIA_VOLUME_INACTIVE = 2;private final int SAFE_MEDIA_VOLUME_ACTIVE = 3;private Integer mSafeMediaVolumeState;private int mMcc = 0;// mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index propertyprivate int mSafeMediaVolumeIndex;// mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,// 安全音量提示针对的是插入耳机的情况private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;// mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.// When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled// automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.private int mMusicActiveMs;  //  超过安全音量使用时长的计时器// 此处就是超过安全音量,使用的最长时间20个小时private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX =  (20 * 3600 * 1000); // 20 hoursprivate static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling intervalprivate static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed// 设置是否启用安全音量private void setSafeMediaVolumeEnabled(boolean on) {Log.d(TAG, "setSafeMediaVolumeEnabled on: " + on);synchronized (mSafeMediaVolumeState) {if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&(mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; // 修改安全音量的状态, 启用// 当超过安全音量使用超过20小时的时候, 执行此处,启用安全音量enforceSafeMediaVolume();  } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) {// 点击警告提示框的确定或者继续加大音量,  执行此处,取消安全音量mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;  // 修改安全音量的状态, 未启用mMusicActiveMs = 0; // 将计时器的时间置为0sendMsg(mAudioHandler,MSG_CHECK_MUSIC_ACTIVE,SENDMSG_REPLACE,0,0,null,MUSIC_ACTIVE_POLL_PERIOD_MS); // 延迟1分钟进行音乐播放检测,执行onCheckMusicActive方法}}}}private void onCheckMusicActive() {  // 检测音乐是否播放synchronized (mSafeMediaVolumeState) {if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {// 因为AudioSystem.STREAM_FM, 底层实际也是用的AudioSystem.STREAM_MUSIC, 因此播放FM时, 也能获取到输出设备int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);if ((device & mSafeMediaVolumeDevices) != 0) {sendMsg(mAudioHandler,MSG_CHECK_MUSIC_ACTIVE,SENDMSG_REPLACE,0,0,null,MUSIC_ACTIVE_POLL_PERIOD_MS); // 此处延迟1分钟, 再执行该方法,重新进行校验int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);// 修改的代码, 添加AudioSystem.STREAM_FM的判断,参照AudioSystem.STREAM_MUSICint index2 = mStreamStates[AudioSystem.STREAM_FM].getIndex(device);if ((AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) && (index > mSafeMediaVolumeIndex))|| (AudioSystem.isStreamActive(AudioSystem.STREAM_FM, 0) && (index2 > mSafeMediaVolumeIndex))) {// 将计时器加上MUSIC_ACTIVE_POLL_PERIOD_MS(1分钟), 因为上面是延迟1分钟再次执行该方法// 这里其实有问题,就是上面执行延迟1分钟执行该方法,延迟的时间可能不精确, 导致计时器的时间可能小于实际播放时长,// 这个在下篇文章MTK的Android10中解决。 因为该版本是Android4.4, 目前还没有出现这中情况mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS;Log.d(TAG, "onCheckMusicActive mMusicActiveMs: " + mMusicActiveMs);// 当超过20小时的时候, 启动安全音量if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {  setSafeMediaVolumeEnabled(true); // 接下来看enforceSafeMediaVolume方法mMusicActiveMs = 0; // 将计时器的置为0}}}}}}private void enforceSafeMediaVolume() {  // 将AudioSystem.STREAM_MUSIC强制设置为安全音量VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];int devices = mSafeMediaVolumeDevices;int i = 0;while (devices != 0) {final int device = 1 << i++;if ((device & devices) == 0) {continue;}int index = streamState.getIndex(device);if (index > mSafeMediaVolumeIndex) {streamState.setIndex(mSafeMediaVolumeIndex, device);sendMsg(mAudioHandler,MSG_SET_DEVICE_VOLUME,SENDMSG_QUEUE,device,0,streamState,0);}// 此处是添加的代码,参考上面的AudioSystem.STREAM_MUSICVolumeStreamState state = mStreamStates[AudioSystem.STREAM_FM];final int fmIndex = state.getIndex(device);if (fmIndex > mSafeMediaVolumeIndex) {state.setIndex(mSafeMediaVolumeIndex, device);sendMsg(mAudioHandler,MSG_SET_DEVICE_VOLUME,SENDMSG_QUEUE,device,0,state,0);// 注意此处,AudioSystem.STREAM_MUSIC在执行MSG_SET_DEVICE_VOLUME消息后, 可以正常的将音量设置为安全音量, 但是AudioSystem.STREAM_FM不行,具体什么原因,还没有去跟代码, 只知道执行下面的代码后, AudioSystem.STREAM_FM可以被修改到安全音量mAudioHandler.postDelayed(new Runnable() {@Overridepublic void run() {int index = mStreamStates[AudioSystem.STREAM_FM].getIndex(device);sendVolumeUpdate(AudioSystem.STREAM_FM, fmIndex, index, 0);}}, 200);}devices &= ~device;}}

此外,关于安全音量(mSafeMediaVolumeIndex)可以在AudioService的构造方法中看到赋值:

public AudioService(Context context) {// ...// The default safe volume index read here will be replaced by the actual value when// the mcc is read by onConfigureSafeVolume()mSafeMediaVolumeIndex = mContext.getResources().getInteger(com.android.internal.R.integer.config_safe_media_volume_index) * 10;
}

34-Android之耳机音量加大时警告提示框问题(展锐SC9820E平台)相关推荐

  1. mt6735 Audio framework]音量警告提示框选择OK,重启后再增大音量希望还会弹出音量警告提示框

    [DESCRIPTION] 目前的做法是: 音量警告提示框选择OK,重启后就不会再弹出警告提示框, 除非恢复出厂设置 如果希望重启后再增大音量希望还会弹出音量警告提示框 请参考如下修改: [SOLUT ...

  2. 芯片与android关系,紫光展锐芯片平台实现与安卓11同步意味着什么

    最近几天,大家都被苹果的新品发布会消息所吸引,其实除了苹果,谷歌也有大动作,其于9月9日凌晨放出了Android 11稳定版,作为目前智能手机市场份额最高的操作系统,Android的升级对于用户的影响 ...

  3. android耳机音量代码,Android链接耳机音量到主音量

    据我所知,这是飞利浦Android TV用户的常见问题(例如 this篇中的第22页,或 that讨论). 一般来说,您的任务的模板是跟踪插入/拔出事件和"系统/音乐"音频流(或媒 ...

  4. android 耳机 音量调节 id,Android链接耳机音量到主音量

    据我所知,这是飞利浦Android TV用户的常见问题(例如 this篇中的第22页,或 that讨论). 一般来说,您的任务的模板是跟踪插入/拔出事件和"系统/音乐"音频流(或媒 ...

  5. php 警告提示框,关于javascript:php重定向到带有警告对话框的页面

    如果注册成功,我需要从php显示一个警告对话框. 我想要重定向到另一个页面. 我的PHP代码在这里: if($conn->query($sql)===TRUE){ echo"alert ...

  6. Android Notification 手机系统横幅弹出提示框调用,横幅通知,RemoteViews使用实例

    直接上代码 :bundle是极光推送的bundle @Override public void onReceive(Context context, Intent intent) {try {Bund ...

  7. php 警告提示框,js弹出对话框(消息框、警告框)

    警告(alert) 在访问网站的时候,你遇到过这样的情况吗?"咚"的一声,一个小窗口出现在你面前,上面写着一段警示性的文字,或是其它的提示信息.如果你不点击确定,你就不能对网页做任 ...

  8. android系统通知栏的弹框流程,Android Notification 手机系统横幅弹出提示框调用

    类似于仿微信信息提示提出框. 在项目当中集成了推送功能,当手机接收到消息后只是在手机通知栏有提示信息.所以需要展示像微信信息弹出框一样的效果,开始自己还以为微信信息弹出框是自定义Dialog之类的自定 ...

  9. Swift - 警告提示框(UIAlertController)的用法

    import UIKitclass ViewController: UIViewController {override func viewDidLoad() {super.viewDidLoad() ...

最新文章

  1. linux 安装反病毒软件
  2. [转]C++中的static关键字的总结
  3. 应用案例:SequoiaDB+Spark搭建医院临床知识库系统
  4. package.json和package-lock.json的区别
  5. Redis-字典(hash)基础
  6. CocoPods原理
  7. JAVA实现随机无重复数字功能
  8. 转帖 一个很有用但不常用到的传值方法! http://topic.csdn.net/u/20070124/22/09d43606-4119-4407-bfa6-8b2890ffbac7.html...
  9. Spring boot 日志 Logback
  10. php跨域问题,PHP跨域问题解决方案
  11. Zemax学习笔记(5)- 设计单透镜实例_2,分析
  12. 求1000以内的素数c语言5个一行,求1000以内的素数用C语言 ,并按每行5个的方式输出...
  13. 猫哥教你写爬虫 040--存储数据-作业
  14. mtk android 多媒体架构,MTK6739核心板
  15. 家用空气净化器除甲醛什么品牌好 能除甲醛吗
  16. EasyNVR网页Chrome无插件播放摄像机视频功能二次开发之云台控制接口示例代码
  17. Pytorch深度学习(五):加载数据集以及mini-batch的使用
  18. 微软 Surface Laptop 系统恢复
  19. 求生之路2不显示局域网服务器,【求生之路2怎么局域网联机】如何局域网联机_求生之路2局域网联机教程_游戏城...
  20. 一张足够长厚5mm的纸折叠多少次高度可以超过珠穆朗玛峰

热门文章

  1. win7下使用EasyBCD硬盘安装centos
  2. EasyBCD引导Ubuntu出错(警告)“EasyBCD and UEFI”
  3. 云终端计算机进入bios,废弃云终端拆解折腾记
  4. java身份证件号格式校验
  5. 农业大数据建设的需求、模式与单品种全产业链推进路径
  6. 畅所欲言吧!神器助你避开毕姥爷那样的饭局门
  7. Python3 菜鸟教程 笔记3 -- 列表和元组
  8. 全国三级联动----省市县 原生js前端
  9. 河南省3加2计算机学校,河南省3+2有哪些学校
  10. 技术总结:winform和wpf的区别 以及 项目的“设计规划”