2015-12-05 3 views
8

Как AudioSessionInitialize и AudioSessionGetProperty устарели, я получаю неправильные значения возврата:iOS 9 Как обнаружить бесшумный режим?

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), я получаю один и тот же неверный результат, независимо от того, в каком состоянии на самом деле устройство. Как я могу определить, включен ли режим молчания на устройстве прямо сейчас?

ответ

5

API больше не доступен. Но работа вокруг проста:

  • Играть короткий звук и обнаружить время, что он заканчивает играть
  • Если время, что он заканчивает играть меньше, чем фактическая длина звука, чем устройство приглушен

Hoishing разместил вспомогательный класс MuteChecker на своем blog. Используйте его как следующее:

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 для кода, который должен работать. Вы можете загрузить его из своего блога напрямую или создать его самостоятельно.

Смежные вопросы