【Android适配问题集锦-音频类】当Android手机插入耳机后仍为外放的尴尬

  • 1、Android耳机插拔检测原理
  • 2、Android耳机插拔检测具体实现
  • 3、真机上的适配问题

澳大利亚悉尼市新南威尔士大学的一名男生在课堂上看色情片,不料耳机没有插好,变成了现场直播。
这里写图片描述
如果在手机上看电影时,当你插上耳机,音乐却从扬声器里响了起来,这未免会更加尴尬了。

1、Android耳机插拔检测原理
Android系统在耳机插入和拔出的时候会发送广播,通过
Broadcast Receiver 监听“android.intent.action.HEADSET_PLUG” 这个Intent来判断耳机是否插拔。

Intent值说明
state0代表拔出,1代表插入
name字符串,代表headset的类型
microphone1代表这个headset有麦克风,0则没有

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

  • Android耳机插拔检测流程图

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

  • WiredAccessoryObserver工作流程图

这里写图片描述
在收到这个广播之后:先执行init()函数,在这个函数中判断要检测的设备是否已经处于连接状态(比如开机之前就已经插上),如果已经连接上就调用updateState立即向系统上报。然后调用startObserving函数监测文件节点路径是否有状态变化,这个函数位于他的父类UEventObserver.java中。在之前建立好的监测中,如果kernel层有uevent事件发送上来则会去匹配这个路径字符串,如果匹配成功会调用在WiredAccessoryObserver重载的onUEvent函数,从event string中解析出devPath, name和state的值,然后继续调用updateState进行处理,在updateState中会对设备的类型进行进一步的分析之后调用update上报,在update中,会往handler中发送一个消息,将耳机的状态报告给Audio系统。之后由AudioService在sendDeviceConnectionIntent函数中向系统广播耳机已经插入的ACTION_HEADSET_PLUG广播,同时会通知AudioPolicy做audio通路切换的工作。

3、真机上的适配问题
(1)在HuaWei T8833上播放音乐,在插入耳机之后耳机和扬声器都会有声音;
updateState中需要进行update操作。
这里写图片描述
通过反编译HuaWei T8833 Framework层WiredAccessoryObserver,我们发现了问题的原因;
这里写图片描述
HDMI状态改变时未进行update操作,也就是没有向系统进行设备连接状态的通知,导致了在插入耳机之后耳机和扬声器都会有声音。

(2)在小米 2S上如果想实现PTT语音消息的功能,播放语音时你可能这样做:
这里写图片描述
使用Audio进行扬声器播放的时候,当插入耳机时声音并未按预期的由耳机输出,而依旧使用的扬声器进行播放。如果您也是这样做的,那么我们建议您在这台机型上将MODE_IN_CALL与STREAM_MUSIC配对或者将SpeakerphoneOn设置为false,从而让程序具有兼容性。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android手机圆角适配有两种方法,一种是使用裁剪图片的方式,另一种是使用圆角布局。下面分别介绍这两种方法的实现。 1. 裁剪图片方式: 首先,在drawable文件夹下新建一个xml文件,命名为“bg_rounded_corners.xml”,并在文件中添加以下代码: ```xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="10dp" /> <solid android:color="@color/white" /> </shape> ``` 其中,corners标签中的radius属性设置圆角半径,solid标签中的color属性设置背景颜色。 然后,在布局文件中使用该drawable文件作为背景,如下所示: ```xml <Button android:id="@+id/btn_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test" android:background="@drawable/bg_rounded_corners" /> ``` 2. 圆角布局方式: 首先,在项目的build.gradle文件中添加以下依赖: ``` dependencies { implementation 'com.makeramen:roundedimageview:2.3.0' } ``` 然后,在布局文件中使用RoundedImageView作为父布局,如下所示: ```xml <com.makeramen.roundedimageview.RoundedImageView android:id="@+id/iv_test" android:src="@drawable/ic_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" app:riv_corner_radius="10dp" app:riv_oval="false" /> ``` 其中,riv_corner_radius属性设置圆角半径,riv_oval属性设置是否为圆形。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值