iOS 音频播放时听筒及扬声器切换

[[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; 
//建议在播放之前设置yes,播放结束设置NO,这个功能是开启红外感应//添加监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sensorStateChange:) name:@"UIDeviceProximityStateDidChangeNotification" object:nil];
//处理监听触发事件
- (void)sensorStateChange:(NSNotificationCenter *)notification{
 //如果此时手机靠近面部放在耳朵旁,那么声音将通过听筒输出,并将屏幕变暗(省电啊)
 if ([[UIDevice currentDevice] proximityState] == YES) { NSLog(@"Device is close to user"); 
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; } else {
 NSLog(@"Device is not close to user"); 
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
  }
}
//初始化播放器的时候如下设置
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof (audioRouteOverride), &audioRouteOverride);
AVAudioSession *audioSession = [AVAudioSession sharedInstance];//默认情况下扬声器播放[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];[audioSession setActive:YES error:nil];

UIDevice 中有两个近距离传感器的属性:proximityMonitoringEnabled 和 proximityState。这两个属性都是 iOS 3.0 及以上才支持的。
//添加近距离事件监听,添加前先设置为YES,如果设置完后还是NO的读话,说明当前设备没有近距离传感器>

[[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; if ([UIDevice currentDevice].proximityMonitoringEnabled == YES) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sensorStateChange:)name:UIDeviceProximityStateDidChangeNotification object:nil]; } //删除近距离事件监听 [[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; if ([UIDevice currentDevice].proximityMonitoringEnabled == YES) { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceProximityStateDidChangeNotification object:nil]; } [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; #pragma mark - 处理近距离监听触发事件 -(void)sensorStateChange:(NSNotificationCenter *)notification { //如果此时手机靠近面部放在耳朵旁,那么声音将通过听筒输出,并将屏幕变暗(省电啊) if ([[UIDevice currentDevice] proximityState] == YES)//黑屏 { NSLog(@"Device is close to user"); [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; }else//没黑屏幕 { NSLog(@"Device is not close to user"); [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; if (![MTool isPlayRecodering]) {//没有播放了,也没有在黑屏状态下,就可以把距离传感器关了 [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; } } }

注意事项(也就是我说的问题)

对于不希望启动接近传感器功能的应用,如果需要进行扬声器和听筒进行切换过程中,则必须通过启用接近传感器来进行声音输出模式的切换,在此时,必须要注意, 如果当声音通过听筒进行播放完毕时,在播放完毕时,此时仍在听筒模式输出,如果此时关闭传感器功能,则导致在离开听筒时,由于传感器功能已经关闭,应用无 法再次收到注册的传感器变更通知,而此时如果未能将底层的声音输出模式切换,则导致相关的声音输出仍从听筒中输出,即使引起传感器反映的障碍已经离开传感 器作用范围,但应用中获取的传感器状态仍未接近状态,使根据传感器状态进行切换声音输出模式操作失效。
特殊情况:
在iPhone 4s及iPhone5中,在接近传感器功能关闭后,如果此时传感器状态为YES,则在再次启动声音传感器时,不会收到传感器的变更通知;
在iPhone 4中,在接近传感器功能关闭后,如果此时传感器状态为YES,则在再次启动声音传感器时,会先收到一次传感器的变更通知;
此 问题的解决方案:当在传感器功能开始时,如果此时传感器传感状态为YES时,此时声音播放结束,仍未出发传感器状态变更时,此时不关闭传感器功能。当引起 传感器反映的障碍已经离开传感器作用范围,此时会收到传感器变更通知,在变更通知中检测当前传感器状态是否为开启状态及声音播放状态,如果在传感器状态为 YES时,而此时需要开启传感器功能的操作(如声音播放功能)已经结束时,则将传感器功能关闭即可;-------也就是说,在不是黑屏的状态下,关闭近传感器功能。就没什么问题了

手动切换两种模式

解决方案:添加长按手势,切换为另一种模式。
代码片段:

UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(longPressed:)];
    [longPressGestureRecognizer setMinimumPressDuration:1.0f];
    [longPressGestureRecognizer setAllowableMovement:50.0];
    [self.bubbleBgImageView addGestureRecognizer:longPressGestureRecognizer];
    [longPressGestureRecognizer release];
---------
- (void)longPressed:(UILongPressGestureRecognizer *) gestureRecognizer
{
    switch (gestureRecognizer.state)
    {
        case UIGestureRecognizerStateEnded:
            break;
        case UIGestureRecognizerStateCancelled:
            break;
        case UIGestureRecognizerStateFailed:
            break;
        case UIGestureRecognizerStateBegan:
            if ([self.voiceDelegate respondsToSelector:@selector(BaseChartVoiceLongPressed)])
            {
                [self.voiceDelegate BaseChartVoiceLongPressed];
            }
            break;
        case UIGestureRecognizerStateChanged:
            break;
        default:
            break;
    }
    }
-------------
#pragma mark BaseChartCellDelegate
- (void)BaseChartVoiceLongPressed {
    NSLog(@"voice long Pressed");
    if ([[[AVAudioSession sharedInstance] category] isEqualToString:AVAudioSessionCategoryPlayback]){
        //切换为听筒播放
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [self showTipInfo:@"切换为听筒模式"];
    }
    else{
        //切换为扬声器播放
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
        [self showTipInfo:@"切换为扬声器模式"];
    }
}

你可能感兴趣的:(iOS 音频播放时听筒及扬声器切换)