android耳机插拔
❶ 安卓耳机模式怎么关闭
这个是一个android系统不常见的问题,有几款机型涉及这个问题。 你找个耳机插拔看看能不能退出了耳机模式,如果能就正常了,或者刷机后发现依然是耳机模式,那基本就是耳机接口的导电问题了
❷ 手机没有声音显示耳机
手机没声音显示耳机图标,证明手机已经与耳机连接成功了。如果耳机里没有声音,是耳机插孔的微动开关故障引起的,可以试着关机再重启试试看。
智能手机(又称作智慧型手机、智能型电话,英语:Smartphone)是对于那些运算能力及功能比传统功能手机更强的手机的集合性称谓。智能手机使用最多的操作系统有:Symbian(已退市)、Windows Phone、Android、IOS和BlackBerry OS,但他们之间的应用软件互不兼容。智能手机因为可以像个人电脑一样安装第三方软件,所以它们功能丰富,而且可以不断扩充。智能手机(Smartphone),是指“像个人电脑一样,具有独立的操作系统,可以由用户自行安装软件、游戏等第三方服务商提供的程序,通过此类程序来不断对手机的功能进行扩充,并可以通过移动通讯网络来实现无线网络接入的这样一类手机的总称”。通常使用的操作系统有:Symbian、Windows Mobile、Windows phone、 iOS、 linux (含Android、 Maemo、 MeeGo 和WebOS)、Palm OS和BlackBerry OS。
❸ 索尼耳机插到安卓手机上不显示耳机图标,耳机里也没有声音!
依据描述~疑似是“时常插拔耳机,以致于插头与耳机孔内金属件接触不良(细微磨损)”
❹ 安卓手机耳机没有声音怎么回事
如果您使用的是华为手机,目前华为手机支持Type-C接口耳机或3.5mm接口耳机,如果出现耳机无声问题,请按照下列内容排查:
请检查耳机接口内是否入液,有异物
建议您用手电筒照射耳机孔,如有异物清洁出来即可;如有入液情况,建议您备份数据,尽快携带手机前往华为客户服务中心进行专业清理。
请交叉验证是否为耳机故障
1. 如果您使用的是华为耳机,建议将耳机插在其他华为手机上进行测试。
如果其他华为手机上也无法使用,可能是耳机损坏,建议更换耳机。
如果其他华为手机上可以正常使用,可能是耳机孔接触不好或者损坏,可尝试重新插拔耳机并适当旋转耳机插头。如果仍然不行,建议备份数据,携带购机凭证前往华为客户服务中心检测。
2. 如果您使用的非华为耳机,可能存在耳机与手机不兼容的问题,建议更换华为原装耳机后尝试使用。
使用转接线后耳机没有声音
如果手机使用转接口之后耳机无声,建议使用原装接口的耳机验证,如果声音正常,可能是转接线与手机接口不兼容,建议您更换转接线。
仍然无法解决您的问题
如果以上方法仍然无法解决您的问题,建议备份好重要数据(第三方通讯类应用需单独备份),携带手机、耳机和购机凭证,前往华为客户服务中心检测。
❺ 安卓手机外放没声音是哪里出了问题
如果您使用的是华为手机,手机外放无声音,可以通过以下方法进行排查处理:
1,查看手机是否显示耳机图标
如果手机未插入耳机,仍显示耳机图标,会导致手机外放无声,出现该现象的原因有多种可能为进入液体、受潮、进灰等情况或者耳机是否标配都可能会影响到耳机孔功能。您可以按照以下方法尝试解决:
(1)、请尝试插拔一次耳机或重启手机进行尝试
(2)、如果耳机孔有入液、进灰等情况,请尝试清理。
(3)、如果您的手机显示仍然异常,请您,提前备份好数据(QQ,微信等第三方应用需单独备份)、携带相关购机凭证,前往附近的华为客户服务中心,获取更多帮助
2,确保喇叭没有被遮挡
3,重启手机或更换播放音源后尝试;
4,获取更多帮助
如果您的手机外放仍然异常,请您提前备份好数据(QQ,微信等第三方应用需单独备份)、携带相关购机凭证,前往附近的华为客户服务中心,获取更多帮助
相关链接如下:客户服务中心预约服务维修备件价格查询寄修服务
❻ android怎么接收耳机插拔广播
接收耳机的广播就可以了!耳机广播为:Intent.ACTION_HEADSET_PLUG ,动态注册!
❼ android声音通道怎么理解
由于使用的是耳机 麦克分离式的耳机,所以要分别上报事件。在Android系统层耳机插孔的检测是基于/sys/class/switch/h2w/state的值来判断的(以4.4.4_r2为例子位于WiredAccessoryManager.java)。
只要在内核中实现一个“或真或假”的基于switch类的h2w开关。Android系统就可以监听到插拔信息。
在播放音乐的时候插入耳机,使用tinymix(参考:Android音频底层调试-基于tinyalsa)命令可以查找到Playback Path的值从SPK变为HP_NO_MIC,就可以说明耳机插拔软件检测正常了。
# tinymix
Mixer name: 'RK_RK616_TINY'
Number of controls: 7
ctl type num name value
0 ENUM 1 Playback Path HP_NO_MIC
1 ENUM 1 Capture MIC Path MIC OFF
2 ENUM 1 Voice Call Path OFF
3 ENUM 1 Voip Path OFF
4 INT 2 Speaker Playback Volume 24 24
5 INT 2 Headphone Playback Volume 24 24
6 ENUM 1 Modem Input Enable ON
❽ android耳机插拔监听做不了全局注册吗
1. 耳机检测的硬件原理
一般的耳机检测包含普通的耳机检测和带mic的耳机检测两种,这两种耳机统称为Headset,而对于不带mic的耳机,一般称之为Headphone。
对于Headset装置的插入检测,一般通过Jack即耳机插座来完成,大致的原理是使用带检测机械结构的耳机插座,将检测脚连到可GPIO中断上,当耳机插入时,耳机插头的金属会碰到检测脚,使得检测脚的电平产生变化,从而引起中断。这样就可以在中断处理函数中读取GPIO的的值,进一步判断出耳机是插入还是拔出。
而对于Headset是否带mic的检测,需要通过codec附加的micbias电流的功能。
Android耳机插拔可以有两个机制实现:
1. InputEvent
2. UEvent
其中UEvent是Android系统默认的耳机插拔机制,所以这里代码是基于UEvent实现的,对于InputEvent机制只是大概看了看,并没有具体实现。
1.1 两种机制的切换
Android默认提供了两种解决方法,那么一定也提供了两种方式的切换,这个提供切换的设置名为config_useDevInputEventForAudioJack( When true use the linux /dev/input/event subsystem to detect the switch changes on the headphone/microphone jack. When false use the older uevent framework),对Android源代码进行全局搜索,可以看到它在frameworks/base/core/res/res/values/config.xml中,默认为false,即不使用InputEvent方式,另外在源码包的厂商相关的文件夹中也找到了相关的设置,如下:
/android/4.2/device/asus/flo/overlay/frameworks/base/core/res/res/values/config.xml
false
/android/4.2/device/samsung/manta/overlay/frameworks/base/core/res/res/values/config.xml
True
可以看到有些厂商的确是使用了InputEvent的方式来进行耳机检测。具体对这个变量的修改是在device下还是frameworks下我想应该都可以,device下可能更好。violet源码device/mstar/mstarnike/overlay/frameworks/base/core/res/res/values/config.xml 中,没有对config_useDevInputEventForAudioJack 设置。
1.2 Android耳机插拨检测流程
2 InputEvent
2.1 Framework层对InputEvent的处理机制
InputEvent的处理主要在frameworks/base/services/java/com/android/server/input/
InputManagerService.java中。在InputManagerService构造函数中,通过如下函数,
mUseDevInputEventForAudioJack = context.getResources().
getBoolean(R.bool.config_useDevInputEventForAudioJack);
判断当前是否通过InputEvent实现耳机插拔检测。
当Android得到InputEvent后,会调用InputManagerService.java中notifySwitch的函数,进而转至WiredAccessoryManager.java文件中的notifyWiredAccessoryChanged函数,之后的流程就和UEvent相同了,在后续会讲到。
2.2 Kernel层的处理机制
Kernel层对耳机插拔InputEvent处理主要是通过input_report_key/input_report_switch(include/linux/input.h)来实现,而在实际使用中,ASOC已经为我们封装好了相应Jack接口函数,只要符合规范就可以拿来使用。下面列出几个常用的接口函数(/sound/soc/soc-jack.c)。
int snd_soc_jack_new(structsnd_soc_codec *codec,
const char *id, int type, struct snd_soc_jack *jack)
生成一个新的jack对象,定义其被检测的类型,即可能插入的设备类型。一般定义为SND_JACK_HEADSET,其余也可以根据接口支持种类添加SND_JACK_LINEOUT,SND_JACK_AVOUT等。
这个函数中调用了snd_jack_new,而在snd_jack_new中可以看到调用 input_allocate_device()分配了input device,就可以在后续产生input event了。
int snd_soc_jack_add_pins(structsnd_soc_jack *jack, int count, struct snd_soc_jack_pin *pins)
将之前定义好的pins加入dapm widgets中,方便dapm统一管理。这一步和InputEvent没有一定联系,可以不调用,主要是可以将耳机插座定义为widgets加入dapm进行省电管理。
viod snd_soc_jack_report(structsnd_soc_jack *jack, int status, int mask)
汇报jack插拔状态,主要完成以下两个工作:
a) 根据插入拔出状态更新前面通过snd_soc_jack_add_pins加入的dapm pin的状态,对其进行上电下电管理。
b) 调用snd_jack_report,在其中通过input_report_key/input_report_switch来向上层汇报input event。
基于上面的函数,可以用以下做法来实现基于InputEvent机制的耳机插拔检测:
a) snd_soc_jack_new 创建jack对象
b) snd_soc_jack_add_pins将其加入到dapm wigets中
c) 通过request irq申请耳机插拔中断,在中断处理函数中通过检测线高低电平判断耳机是插入还是拔出,通过读取codec寄存器来判断是headset还是headphone
d) 根据判断结果调用snd_soc_jack_report发送InputEvent
此外,ASOC还提供了一个封装好的函数来实现上述c)和d)步骤的功能:
int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios)
该函数通过标准GPIO驱动申请GPIO及GPIO对应中断,并提供了统一的中断处理函数来汇报事件。此函数只适用于耳机中断接至GPIO且GPIO驱动为Linux标准驱动的情况下,并且不支持mic检测。
3. UEvent
3.1 Switch 基本原理
Switch是Android引进的新的驱动,目的是用于检测一些开关量,比如检测耳机插入、检测 USB 设备插入等。Switch在sysfs文件系统中创建相应entry,用户可以通过sysfs与之交互; 此外还可以通过uevent机制与之交互, 从而检测switch状态。
3.1.1 Switch的实现
Switch class在Android中实现为一个mole,可动态加载;而具体的switch gpio则是基于 platform device框架。代码在drivers\switch\switch_class.c和drivers\switch\switch_gpio.c中。其中switch_class.c实现了一个switch class,而switch_gpio.c则是这个class中的一个device,即针对gpio的一个switch设备。
switch_class.c文件创建了一个switch_class,实现了内核的switch机制,提供支持函数供其他switch device驱动调用。
static int __init switch_class_init(void){
return create_switch_class(); }
static void __exit switch_class_exit(void){
class_destroy(switch_class); }
mole_init(switch_class_init);
mole_exit(switch_class_exit);
init函数调用create_switch_class->class_create创建switch_class设备类。相对应 exit则是销毁这个设备类。
该文件导出两个函数供其他switch设备驱动调用,分别是注册switch设备switch_dev_register和注销switch_dev_unregister(drivers/switch/switch_class.c)。
int switch_dev_register(struct switch_dev *sdev)
{
int ret;
if (!switch_class) {
ret = create_switch_class();
if (ret < 0)
return ret;
}
sdev->index = atomic_inc_return(&device_count);
sdev->dev = device_create(switch_class, NULL,
MKDEV(0, sdev->index), NULL, sdev->name);
if (IS_ERR(sdev->dev))
return PTR_ERR(sdev->dev);ret = device_create_file(sdev->dev, &dev_attr_state);
if (ret < 0)
goto err_create_file_1;
ret = device_create_file(sdev->dev, &dev_attr_name);
if (ret < 0)
goto err_create_file_2;dev_set_drvdata(sdev->dev, sdev);
sdev->state = 0;
return 0;
err_create_file_2:
device_remove_file(sdev->dev, &dev_attr_state);
err_create_file_1:
device_destroy(switch_class, MKDEV(0, sdev->index));
printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name);return ret;
}
EXPORT_SYMBOL_GPL(switch_dev_register);void switch_dev_unregister(struct switch_dev *sdev)
{
device_remove_file(sdev->dev, &dev_attr_name);
device_remove_file(sdev->dev, &dev_attr_state);
dev_set_drvdata(sdev->dev, NULL);
device_destroy(switch_class, MKDEV(0, sdev->index));
}
EXPORT_SYMBOL_GPL(switch_dev_unregister);
然后是两个sysfs操作函数(state_show和name_show),分别用于输出switch device的name和state。当用户读取sysfs中对应的switch entry(/sys/class/switch/<dev_name>/name和/sys/class/switch/<dev_name>/state)时候,系统会自动调用这两个函数向用户返回switch设备的名称和状态。
static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct switch_dev *sdev = (struct switch_dev *)dev_get_drvdata(dev);
if (sdev->print_state) {
int ret = sdev->print_state(sdev, buf);
if (ret >= 0)
return ret;
}
return sprintf(buf, "%d\n", sdev->state);
}static ssize_t name_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct switch_dev *sdev = (struct switch_dev *)dev_get_drvdata(dev);
if (sdev->print_name) {
int ret = sdev->print_name(sdev, buf);
if (ret >= 0)
return ret;
}
return sprintf(buf, "%s\n", sdev->name);
}
可见,这两个函数就是直接调用对应的switch_dev中的print_state和print_name函数;如果没有定义这两个函数,则调用sprintf把信息打印到buf缓冲区里。
最后是 switch_set_state 函数,该函数是内核内部使用,并不为用户调用,它完成的功能主要是两件事: 调用name_show和state_show输出switch设备名称和状态至sysfs文件系统;发送uevent通知用户switch device的信息(名称和状态) 。
switch_gpio.c文件基于switch class实现了一个gpio的switch设备驱动,其实现的原理如下: 基于platform device/driver框架,在probe函数中完成初始化,包括获取gpio的使用权限,设置gpio方向为输入,注册switch_dev设备,为gpio分配中断,指定中断服务程序,初始化一个gpio_switch_work工作,最后读取gpio初始状态。
当 GPIO 引脚状态发生变化时,则会触发中断,在中断服务程序中调用schele_work,这个被schele的work即前面初始化的gpio_switch_work,最后这个work被执行,在gpio_switch_work函数中读取当前gpio电平,调用 switch_set_state更新sysfs并通过 uevent通知上层应用。
这个设备驱动只实现了print_state函数:switch_gpio_print_state,没有实现 print_name函数。当gpio_switch_work执行的时候,里面调用switch_set_state->switch_gpio_print_state输出GPIO状态到 sysfs。
3.1.2 Switch模块的用户接口
sysfs文件为sys/class/switch/<dev_name>/name, sys/class/switch/<dev_name>/state,uevent环境变量为SWITCH_NAME=<name>, SWITCH_STATE=<state>。sysfs文件系统和uevent机制。
UEvent机制比较简单,它基于switch driver,switch driver会在Android建立耳机插拔的目录/sys/devices/virtual/switch/h2w,在此目录下有个设备结点名为state,driver通过更新state的值,从而通知Android上层耳机状态的改变。
3.2 Framework层对UEvent的处理机制
Android在frameworks/base/services/java/com/android/server/WiredAccessoryManager. java中实现针对UEvent的机制。
在这个文件中,从UEventObserver中继承了类WiredAccessoryObserver,在makeObservedUEventList中将要观察的事件加入到UEvent系统中:
if(!mUseDevInputEventForAudioJack)
{
uei = new UEventInfo(NAME_H2W,BIT_HEADSET, BIT_HEADSET_NO_MIC);
……
}
可以看到,只有当不使用InputEvent时才添加UEvent事件,NAME_H2W就是headphone对应的switch driver的名字。BIT_HEADSET和BIT_HEADSET_NO_MIC是state结点的两个值,分别表示有mic和无mic的耳机。
当UEvent事件到来时,类WiredAccessoryObserver中重载的onUEvent函数会被回调,从而调用updateStateLocked(devPath,name, state) ,其中state的值就是通过/sys/devices/virtual/switch/h2w/state结点来获得。
最后,程序会进入setDeviceStateLocked函数中处理,在setDeviceStateLocked中根据state的值设置device,然后调用mAudioManager.setWiredDeviceConnectionState,最后进入AudioPolicyManagerBase::setDeviceConnectionState。
3.3 Kernel层的机制
前面说过,基于UEvent的耳机检测机制需要实现一只switch driver,它会建立一个用于耳机插拔检测的目录/sys/devices/virtual/switch/h2w,在此目录下有个设备结点名为state,switch driver通过更新state的值,从而通知Android上层耳机状态的改变。
switch driver的目录在Linux kernel的drivers/staging/android/switch目录下,可以从目录名称中看到这只driver是为了Android专门产生的。在switch目录下有两个已有文件,switch_class.c是switch driver的内部实现,它提供了switch driver所需的一些API;switch_gpio.c是一个例子,它实现了一个基于GPIO中断的switch driver。
另外,在drivers/switch目录下也有同样的文件,不同之处是两者在Android下生成的结点的位置不同,如果要按照drivers/switch目录下的switch driver来实现,需要更改WiredAccessoryManager.java文件。
下面讲讲如何添加switch driver。添加switch driver很简单,可以仿照switch_gpio.c,大致步骤如下:
a) 在drivers/staging/android/switch目录下新建一个platform driver,其中包含一个全局变量struct switch_dev sdev,即要注册的switch device。
b) 在platformdriver的probe函数中调用switch_dev_register将前面的sdev注册到系统中。
c) 申请用于耳机检测的中断处理函数。对于耳机插拔来说,由于用户的插拔快慢等可能产生多次中断,所以一般是在中断处理函数中实现一个延时工作队列,即INIT_DELAYED_WORK,在队列的回调函数中来进行实际判断。
d) 当中断发生后,通过switch_set_state设置state节点的值,这个值要和WiredAccessoryManager.java文件中定义的一致,可参看BIT_HEADSET和BIT_HEADSET_NO_MIC的定义。目前是0表示无耳机插入,1表示带Mic的耳机,2表示不带Mic的耳机。switch_set_state这个函数调用了kobject_uevent_env/kobject_uevent,这两个函数就是kernel通过uevent来通知user space的核心函数了。
❾ 为什么我的耳机叉不进手机,小米4 是安卓的耳机呀
1,这种情况应该是这台小米4手机进入耳机模式了。
2,应该是耳机孔微动开关失效引起的,就是耳机已拔出,但开关并没及时断开导致的。
3,可以尝试多次快速的插拔耳机试试看或是重新启动手机试试看。
4,如果还是不行的话,应该要拿到小米手机的售后网点检测一下或更换新的耳机插孔。
❿ 安卓手机显示耳机模式怎么关闭
按照如下方法进行操作:
1、耳机模式是在有耳机插入的情况下才会出现的。
2、如果没有插入耳机,可以看看耳机插孔里面是不是有异物。
3、如果没有任何异物,可尝试重启一下,然后播放音乐或视频,看看是否有外音。
4、如果没有插耳机、插孔内也没有异物、播放音频和视频都没有外音的话,可能就是系统错误。建议到手机售后维修点刷机,若在保修期内,这种工作是免费的。
拓展资料
手机耳机模式解决方法:
1、点击手机设置。