ios开发 静音键设置_iOS获取设备静音键的开关状态 误差优化

本文探讨了在iOS中检测物理静音键状态的方法,包括使用API、播放白噪音计数和第三方解决方案,分析了存在的误差并提出了优化方案。优化策略包括避免使用runloop,改用播放时间戳判断,以及确保AVAudioSession激活和声道资源未被占用。最终提供了实现代码的demo链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题记:检测苹果手机的物理静音按键的开关状态

最近业务上有个需求就是以静音键的状态来做一些逻辑显示,但是在iOS5以后,苹果就没有开放现成的api来获取静音键的状态。只要遇到这样的情况,基本都是“曲线救国”。

目前网上基本获取静音键的状态大体有三种方式:

第一种:使用对应的api获取

CFStringRef state = nil;

UInt32 propertySize = sizeof(CFStringRef);

AudioSessionInitialize(NULL, NULL, NULL, NULL);

OSStatus status = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);

if (status == kAudioSessionNoError){

return (CFStringGetLength(state) == 0); // YES = silent

}

return NO;

试了试,但是获取状态不正确。

第二种方式:

通过播放一段短的白噪音,根据回调时间差来计数,然后根据计数的大小来判断是否静音。参考文献.

但是这种方式的获取也存在一些误差,在某些情况下,由于runloop的时机,以及计数的误差,加上判断阀值的设定,总会有些误差导致有那么几次静音键的状态获取不对。

第三种方式:

国外大佬的解决方案,SoundSwitch.zip.但是此地址打开失败。

综合以上情况,最后选择了第二种方式来获取静音键的开关状态。所以一直在查找那些为什么状态获取失败的原因。

在我调试的时候,发现在静音键关闭的时候,获取状态为开的时候,获取音量的值始终为0.

[[AVAudioSession sharedInstance] outputVolume]

至此,可以知道有两个地方的影响,导致获取静音键按钮的开光状态的误差原因。

1、在某些情况下,由于runloop的时机,以及计数的误差,加上判断阀值的设定,导致判断出错。

2、当前获取音量的值为0影响了获取结果。

优化方案:

1、摒弃runloop技术策略,改用播放时间戳的判断。因为上面demo的思想就是播放一个短音效。所以根据前后播放时间差的判断,规避由于计数器的判断误差。

2、针对获取音量的值为0情况,一般都是AVFoundation获取音量的时候,播放器没有激活。或者播放器声道资源被占用。所以在每一次播放白噪音时,提前设置AVAudioSession,并且播放一次音频,确保在获取前声道没有被第三方或者APP里面的其他播放业务打断。

猜测,静音键按钮的状态 是根据声卡、获取音量的值有联系。如果获取音量的值为0(不管是获取正确的音量值是0,还是因为获取错误的音量值为0),那么默认就是静音的状态。

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];//保证不会打断第三方app的音频播放 导致获取不准确

NSString *itemVideoPath = [[NSBundle mainBundle] pathForResource:@"detection" ofType:@"aiff"];

AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:itemVideoPath]];

[player play];

最终解决方案代码:

demo地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值