iOS 9 如何检测静音模式?

Posted

技术标签:

【中文标题】iOS 9 如何检测静音模式?【英文标题】:iOS 9 How to Detect Silent Mode? 【发布时间】:2015-12-05 12:42:08 【问题描述】:

由于 AudiosessionInitializeAudioSessionGetProperty 已被弃用,我得到了错误的返回值:

CFStringRef state = nil;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
OSStatus status = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
[[AVAudioSession sharedInstance] setActive:YES error:nil];
if (status == kAudioSessionNoError) 
    return CFStringGetLength(state) == 0;   // YES = silent

return NO;

从这段代码(我发现它here),无论设备实际处于什么状态,我都会得到相同的错误结果。如何检测设备上的静音模式是否已开启?

【问题讨论】:

【参考方案1】:

API 不再可用。但解决方法很简单:

播放一段短音频并检测它播放完毕的时间 如果完成播放的时间短于音频的实际长度,则设备静音

Hoishing 在他的blog 上发布了一个助手类MuteChecker。如下使用它:

self.muteChecker = [[MuteChecker alloc] initWithCompletionBlk:^(NSTimeInterval lapse, BOOL muted) 
    NSLog(@"muted: %d", muted);
];
[self.muteChecker check];

这是该类的完整代码,您可以简单地复制过去到您的项目中:

MuteChecker.h

#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>

typedef void (^MuteCheckCompletionHandler)(NSTimeInterval lapse, BOOL muted);

// this class must use with a MuteChecker.caf (a 0.2 sec mute sound) in Bundle
@interface MuteChecker : NSObject
-(instancetype)initWithCompletionBlk:(MuteCheckCompletionHandler)completionBlk;
-(void)check;
@end

MuteChecker.cpp

#import "MuteChecker.h"

void MuteCheckCompletionProc(SystemSoundID ssID, void* clientData);

@interface MuteChecker ()
@property (nonatomic,assign) SystemSoundID soundId;
@property (strong) MuteCheckCompletionHandler completionBlk;
@property (nonatomic, strong)NSDate *startTime;
-(void)completed;
@end

void MuteCheckCompletionProc(SystemSoundID ssID, void* clientData)
    MuteChecker *obj = (__bridge MuteChecker *)clientData;
    [obj completed];


@implementation MuteChecker

-(void)playMuteSound

    self.startTime = [NSDate date];
    AudioServicesPlaySystemSound(self.soundId);


-(void)completed

    NSDate *now = [NSDate date];
    NSTimeInterval t = [now timeIntervalSinceDate:self.startTime];
    BOOL muted = (t > 0.1)? NO : YES;
    self.completionBlk(t, muted);


-(void)check 
    if (self.startTime == nil) 
        [self playMuteSound];
     else 
        NSDate *now = [NSDate date];
        NSTimeInterval lastCheck = [now timeIntervalSinceDate:self.startTime];
        if (lastCheck > 1)     //prevent checking interval shorter then the sound length
            [self playMuteSound];
        
    


- (instancetype)initWithCompletionBlk:(MuteCheckCompletionHandler)completionBlk

    self = [self init];
    if (self) 
        NSURL* url = [[NSBundle mainBundle] URLForResource:@"MuteChecker" withExtension:@"caf"];
        if (AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &_soundId) == kAudioServicesNoError)
            AudioServicesAddSystemSoundCompletion(self.soundId, CFRunLoopGetMain(), kCFRunLoopDefaultMode, MuteCheckCompletionProc,(__bridge void *)(self));
            UInt32 yes = 1;
            AudioServicesSetProperty(kAudioServicesPropertyIsUISound, sizeof(_soundId),&_soundId,sizeof(yes), &yes);
            self.completionBlk = completionBlk;
         else 
            NSLog(@"error setting up Sound ID");
        
    
    return self;


- (void)dealloc

    if (self.soundId != -1)
        AudioServicesRemoveSystemSoundCompletion(self.soundId);
        AudioServicesDisposeSystemSoundID(self.soundId);
    


@end

重要提示:您还必须提供一个简短的音频MuteChecker.caf 才能使代码正常工作。您可以直接从他的博客下载一个或自己生成一个。

【讨论】:

以上是关于iOS 9 如何检测静音模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测iOS设备是否处于静默模式?

在 iOS 7 中检测静音模式

如何使用 Adob​​e air 在静音模式下检测设备并与之交互 - AS3

如何以编程方式检测 android 手机是不是处于静音模式

如何检测音频是不是无法静音?

在 iOS 5 中检测 iPhone 静音开关