iOS音量和静音按键状态获取

项目中需要用到判断当前手机音量是否为0或者静音按键是否关闭的状态,本来以为这应该有现成的接口,但没找到,而且获取静音按键的状态还有点麻烦,所以在此记录下。

一. 获取手机系统的音量

获取音量是通过获取MPVolumeSlider来获取的,这里封装成类方法,通过objc_setAssociatedObject关联来存储。

/// 是否系统音量 静音
+ (BOOL)isSystmeVolumeMute {
    NSLog(@"volume = %f", [self systemVolume]);
    return ([self systemVolume] < 0.001) ? YES : NO;
}

/// 系统 音量
+ (float)systemVolume {
    CGFloat volume = [self volumeViewSlider].value;
    if (volume == 0) {
        volume = [[AVAudioSession sharedInstance] outputVolume];
    }
    return volume;
}

#pragma mark - 系统 音量
/// 系统 音量 指示器
+ (UISlider *)getSystemVolumeViewSlider {
    MPVolumeView *volumeView = [[MPVolumeView alloc] init];
    UISlider *volumeViewSlider = nil;
    for (UIView *view in [volumeView subviews]){
        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
            volumeViewSlider = (UISlider *)view;
            [self setVolumeViewSlider:volumeViewSlider];
            break;
        }
    }
    return volumeViewSlider;
}

+ (void)setVolumeViewSlider:(UISlider *)volumeViewSlider {
    objc_setAssociatedObject(self, @selector(volumeViewSlider), volumeViewSlider, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (UISlider *)volumeViewSlider {
    UISlider *tmpSlider =  objc_getAssociatedObject(self, @selector(volumeViewSlider));
    if (!tmpSlider) {
        tmpSlider = [self getSystemVolumeViewSlider];
    }
    return tmpSlider;
}

二.获取静音按键状态

因为静音按键状态的方法在iOS7之后被废弃了,所以只能通过折中的方法来获取。

静音按键处于静音状态时,如果执行音频文件的播放,会立即执行结束的回调函数。因此可以利用这个特性来判断当前静音按键是否处于静音状态。

这里的方法是播放一段0.1秒的音频文件,然后开始播放的时候记录当前的时间,在播放结束的回调里,获取跟开始播放的时间之间的差值,如果这个差值小于0.1秒,那就说明当前静音按键是关闭的,如果大于0.1秒,就说明静音按键是打开的。

/// 检测 静音 按键 状态
+ (void)detectSystemMuteStatusWithMuteSwitchBlock:(FJFSystemMuteHelperMuteSwitchBlock)muteSwitchBlock {
    _muteSwitchBlock = [muteSwitchBlock copy];
    _kFJFSystemMuteHelperStartTime = [[NSDate date] timeIntervalSince1970];
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"detection" ofType:@"aiff"];
    NSURL *fileUrl = [NSURL URLWithString:filePath];
    SystemSoundID soundID = 0;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
    AudioServicesAddSystemSoundCompletion(soundID,NULL,NULL,soundCompleteCallBack,NULL);
    AudioServicesPlaySystemSound(soundID);
}


#pragma mark -------------------------- Private Methods

void soundCompleteCallBack(SystemSoundID soundID, void *clientData) {
   AudioServicesRemoveSystemSoundCompletion (soundID);
    BOOL isMute = NO;
    double endTime = [[NSDate date] timeIntervalSince1970];
    double diffTime = endTime - _kFJFSystemMuteHelperStartTime;
    if (diffTime < 0.01) {
        isMute = YES;
    }
    
    if (_muteSwitchBlock) {
        _muteSwitchBlock(isMute);
    }
}

这里封装为类方法,通过block进行回调,由于`静音按状态获取的时间很短,有点类似同步的回调。

三.类方法

这里提供了四个类方法,分别来获取系统音量、系统音量是否静音、检测静音按键的状态、检测系统音量或者静音按键是否有一个为静音。

/**
 是否系统音量 静音

 @return 是否 静音
 */
+ (BOOL)isSystmeVolumeMute;

/**
 系统 音量

 @return 系统 音量
 */
+ (float)systemVolume;
/**
 检测 静音按键 或 系统音量 两者是否 有一个 静音

 @param muteSwitchBlock 状态 回调
 */
+ (void)detectAllSystemMuteWithMuteSwitchBlock:(FJFSystemMuteHelperMuteSwitchBlock)muteSwitchBlock;
/**
 检测 静音 按键 状态

 @param muteSwitchBlock 状态 回调
 */
+ (void)detectSystemMuteStatusWithMuteSwitchBlock:(FJFSystemMuteHelperMuteSwitchBlock)muteSwitchBlock;

具体详见FJFSystemMuteDemo

四.最后

如果大家有什么疑问或者意见向左的地方,欢迎大家留言讨论。

你可能感兴趣的:(iOS音量和静音按键状态获取)