当前位置: 首页 > news >正文

腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?

腾讯优测是专业的移动自动化测试平台,提供多维度的自动化测试服务,让测试更简单!
近期有报道称,澳大利亚悉尼市新某大学的一名男生在课堂上看电影,不料耳机没有插好,变成了现场直播。。。

如果你认为耳机没插好事件尚且可以hold住,那么接下来的问题会不会让你更加尴尬?当你在手机插上耳机准备看电影时,声音却从扬声器里响了出来。。。
没想到藏得这么深,还是让耳机出卖了。。。

容我静静,为避免此类尴尬事件再次发生,我特意对耳机在手机上的插拔原理研究了一番。感兴趣的朋友我们可以一起讨论。。。
1、Android耳机插拔检测原理
Android系统在耳机插入和拔出的时候会发送广播,通过Broadcast Receiver 监听”android.intent.action.HEADSET_PLUG” 这个Intent来判断耳机是否插拔。

2、Android耳机插拔检测具体实现
在Android4.0以上的版本,耳机插拔检测的源文件位于frameworks/base/services/java/com/android/server/WiredAccessoryObserver.java;(4.1及以上是WiredAccessoryManager.java;在android4.0以前是HeadsetObserver.java)顾名思义,它主要是用来检测有线的设备连接状态。
Android耳机插拔检测流程图

我们重点来看一下WiredAccessoryObserver
WiredAccessoryObserver继承自Observed(Android耳机插拔可以有两个机制实现:Input Event和Event),从该文件的路径可以得知,这个类位于service目录,应该是在android系统服务初始化的时候实例化的,在这个类的构造方法中,注册了一个广播接收器用来接收系统启动完毕的广播。


WiredAccessoryObserver工作流程图


在收到这个广播之后:先执行i nit()函数,在这个函数中判断要检测的设备是否已经处于连接状态(比如开机之前就已经插上),如果已经连接上就调用gestate立即向系统上报。
然后调用observing函数监测文件节点路径是否有状态变化,这个函数位于他的父类Observed.java中。在之前建立好的监测中,如果kernel层有event事件发送上来则会去匹配这个路径字符串,如果匹配成功会调用在WiredAccessoryObserver重载的eventful函数,从event string中解析出death, name和state的值,然后继续调用gestate进行处理。
在gestate中会对设备的类型进行进一步的分析之后调用update上报,在update中,会往handler中发送一个消息,将耳机的状态报告给Audio系统。之后由Audio Service在antivivisectionist函数中向系统广播耳机已经插入的ACTION_HEADSET_PLUG广播,同时会通知Audio Policy做audio通路切换的工作。
3、真机上的适配问题
(1)在Aweigh T8833上播放音乐,在插入耳机之后耳机和扬声器都会有声音。
gestate中需要进行update操作:

通过反编译Aweigh T8833 Framework层WiredAccessoryObserver,我们发现了问题的原因:


HDMI状态改变时未进行update操作,也就是没有向系统进行设备连接状态的通知,导致了在插入耳机之后耳机和扬声器都会有声音。
(2)在小米 2S上如果想实现PTT语音消息的功能,播放语音时你可能这样做:


使用Audio进行扬声器播放的时候,当插入耳机时声音并未按预期的由耳机输出,而依旧使用的扬声器进行播放。如果您也是这样做的,那么我们建议您在这台机型上将MODE_IN_CALL与STREAM_MUSIC配对或者将Answerphone设置为false,从而让程序具有兼容性。
_
腾讯优测是专业的移动云测试平台,为应用、游戏、H5混合应用的研发团队提供产品质量检测与问题解决服务。不仅在线上平台提供自动化兼容性测试、云手机远程租用与调试、漏洞分析、自动化测试工具Xtest等多种质量检测工具,更为VIP客户配备了专家团队提供定制化综合测试解决方案。

相关文章:

  • Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)...
  • jdbc conn.commit()提交事务和 rollback()使用
  • 每天一个linux命令:mkdir命令
  • 程序(进程)内存分布解析【转】
  • jenkins updatecenter更新插件有问题
  • Django+uwsgi+Nginx安装部署
  • 基于人脸识别的商业大数据4
  • 用xargs批量删除Redis的keys的技巧
  • php中的邮件技术
  • 一起参Ember.js讨论、问答社区。
  • 初学Redis(1)——认识Redis
  • 移动端流体布局
  • MongoDB sharding迁移那些事(三)
  • [转]Oracle 阳历转农历
  • V-rep学习笔记:转动关节1
  • angular组件开发
  • Docker 笔记(2):Dockerfile
  • ECMAScript6(0):ES6简明参考手册
  • HTTP中GET与POST的区别 99%的错误认识
  • java多线程
  • Material Design
  • MySQL-事务管理(基础)
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • vue:响应原理
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 读懂package.json -- 依赖管理
  • 分布式任务队列Celery
  • 分享一份非常强势的Android面试题
  • 缓存与缓冲
  • 前端技术周刊 2019-01-14:客户端存储
  • 前言-如何学习区块链
  • 如何在GitHub上创建个人博客
  • 云大使推广中的常见热门问题
  • 自动记录MySQL慢查询快照脚本
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • #FPGA(基础知识)
  • #大学#套接字
  • (007)XHTML文档之标题——h1~h6
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (八)c52学习之旅-中断实验
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .Net Core与存储过程(一)
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • /boot 内存空间不够
  • /var/spool/postfix/maildrop 下有大量文件