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];
引用:http://www.cnblogs.com/linyawen/archive/2012/08/24/2654474.html
--------------------看什麼看,這是分割線。再看把你也割了--------------------------------
這裡是新的補充,因為上面的做法在實際應用中可能會有一些問題,以前只是看了一下,沒有應用到實際的項目中。
在 iOS 中,並非所有 iOS 裝置都擁有近距離感應器。這裡介紹如何調用 iPhone 的距離感應器。
使用近距離感應器
UIDevice 中有兩個近距離感應器的屬性:proximityMonitoringEnabled 和 proximityState。這兩個屬性都是 iOS 3.0 及以上才支援的。
proximityMonitoringEnabled 屬性
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.
要確定近距離感應器是否可用,可以嘗試啟用它,即 proximityMonitoringEnabled = YES,如果設定的屬性值仍然為NO,說明感應器不可用。
proximityState 屬性
感應器已啟動前提條件下,如果使用者接近 近距離感應器,此時屬性值為YES,並且螢幕已關閉(非休眠)。And vice versa。
Notification
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 = [[UILongPressGestureRecognizeralloc] initWithTarget:self
action:@selector(longPressed:)];
[longPressGestureRecognizersetMinimumPressDuration:1.0f];
[longPressGestureRecognizersetAllowableMovement:50.0];
[self.bubbleBgImageViewaddGestureRecognizer:longPressGestureRecognizer];
[longPressGestureRecognizerrelease];
---------
-(void)longPressed:(UILongPressGestureRecognizer *) gestureRecognizer
{
switch (gestureRecognizer.state)
{
caseUIGestureRecognizerStateEnded:
break;
caseUIGestureRecognizerStateCancelled:
break;
caseUIGestureRecognizerStateFailed:
break;
caseUIGestureRecognizerStateBegan:
if ([self.voiceDelegaterespondsToSelector:@selector(BaseChartVoiceLongPressed)])
{
[self.voiceDelegateBaseChartVoiceLongPressed];
}
break;
caseUIGestureRecognizerStateChanged:
break;
default:
break;
}
}
-------------
#pragma mark BaseChartCellDelegate
-(void)BaseChartVoiceLongPressed
{
NSLog(@"voice long Pressed");
if ([[[AVAudioSessionsharedInstance]category] isEqualToString:AVAudioSessionCategoryPlayback])
{
//切換為耳機播放
[[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryPlayAndRecorderror:nil];
[selfshowTipInfo:@"切換為耳機模式"];
}
else
{
//切換為擴音器播放
[[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryPlaybackerror:nil];
[selfshowTipInfo:@"切換為擴音器模式"];
}
}