[[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];
To determine if proximity monitoring is available, attempt to enable it. If the value of the proximityState property remains NO, proximity monitoring is not available.
UIDeviceProximityStateDidChangeNotification,當近距離傳感器狀態改變時發生。
//添加近距離事件監聽,添加前先設置為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:@"切換為揚聲器模式"]; } }