我似乎無法在SDK中找到如何以編程方式感知iPhone上的靜音按鈕/開關。當我的應用程序播放背景音樂時,它會正確響應音量按鈕,而我沒有任何代碼可以遵循,但是,當我使用靜音開關時,它只會繼續播放。如何以編程方式感應iPhone靜音開關?
如何測試靜音的位置?
(注:我的程序有自己的靜音開關,但我想在物理交換機來覆蓋。)
謝謝!
我似乎無法在SDK中找到如何以編程方式感知iPhone上的靜音按鈕/開關。當我的應用程序播放背景音樂時,它會正確響應音量按鈕,而我沒有任何代碼可以遵循,但是,當我使用靜音開關時,它只會繼續播放。如何以編程方式感應iPhone靜音開關?
如何測試靜音的位置?
(注:我的程序有自己的靜音開關,但我想在物理交換機來覆蓋。)
謝謝!
謝謝,JPM。事實上,鏈接,您提供線索,以正確的答案;爲了完整(因爲SO應該是快速解答的來源!)...
// "Ambient" makes it respect the mute switch
// Must call this once to init session
if (!gAudioSessionInited)
{
AudioSessionInterruptionListener inInterruptionListener = NULL;
OSStatus error;
if ((error = AudioSessionInitialize (NULL, NULL, inInterruptionListener, NULL)))
{
NSLog(@"*** Error *** error in AudioSessionInitialize: %d.", error);
}
else
{
gAudioSessionInited = YES;
}
}
SInt32 ambient = kAudioSessionCategory_AmbientSound;
if (AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (ambient), &ambient))
{
NSLog(@"*** Error *** could not set Session property to ambient.");
}
Sho''nuff! 快速回顧:「AudioSessionSetProperty將AudioCategory設置爲Ambient」(我相信可以談論發貨軟件......) 謝謝! – Olie 2008-11-15 07:42:11
這裏有兩個例子來說明如何使用AudioSessionInitialize(最終): http://www.restoroot.com/Blog/2008/12/25/audiosessioninitialize-workarounds/
我這裏遵循的一般理論,得到了這個工作 http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/
這裏有一個概括:播放一小段沉默的聲音。時間需要多長時間才能播放。如果靜音開關打開,聲音的播放將比聲音本身短得多。我使用了500ms的聲音,如果聲音播放時間少於此時間,則靜音開關打開。我使用音頻服務來播放無聲的聲音(始終尊重靜音開關)。本文說您可以使用AVAudioPlayer播放此聲音。如果您使用AVAudioPlayer,我假設您需要設置您的AVAudioSession類別以遵守靜音開關,但我沒有嘗試過。
要了解靜音開關和的音量控制狀態,我寫了這兩個函數。如果您希望在嘗試創建音頻輸出之前警告用戶,這些都是理想之選。
-(NSString*)audioRoute
{
CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
if(n)
{
// TODO: Throw an exception
NSLog(@"AudioSessionGetProperty: %@", osString(n));
}
NSString *result = (NSString*)state;
[result autorelease];
return result;
}
-(Float32)audioVolume
{
Float32 state;
UInt32 propertySize = sizeof(CFStringRef);
OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume, &propertySize, &state);
if(n)
{
// TODO: Throw an exception
NSLog(@"AudioSessionGetProperty: %@", osString(n));
}
return state;
}
-(BOOL)isDeviceMuted
{
CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
return (CFStringGetLength(state) > 0 ? NO : YES);
}
我回答了類似的問題here (link)。相關代碼:
-(BOOL)silenced {
#if TARGET_IPHONE_SIMULATOR
// return NO in simulator. Code causes crashes for some reason.
return NO;
#endif
CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
if(CFStringGetLength(state) > 0)
return NO;
else
return YES;
}
一些在其他的答案(包括接受的答案)的代碼,如果你不是在環境模式,在靜音開關的尊重可能無法正常工作。
我寫下例程切換到環境,閱讀開關,然後返回到我的應用程序需要的設置。
-(BOOL)muteSwitchEnabled {
#if TARGET_IPHONE_SIMULATOR
// set to NO in simulator. Code causes crashes for some reason.
return NO;
#endif
// go back to Ambient to detect the switch
AVAudioSession* sharedSession = [AVAudioSession sharedInstance];
[sharedSession setCategory:AVAudioSessionCategoryAmbient error:nil];
CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
BOOL muteSwitch = (CFStringGetLength(state) <= 0);
NSLog(@"Mute switch: %d",muteSwitch);
// code below here is just restoring my own audio state, YMMV
_hasMicrophone = [sharedSession inputIsAvailable];
NSError* setCategoryError = nil;
if (_hasMicrophone) {
[sharedSession setCategory: AVAudioSessionCategoryPlayAndRecord error: &setCategoryError];
// By default PlayAndRecord plays out over the internal speaker. We want the external speakers, thanks.
UInt32 ASRoute = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
sizeof (ASRoute),
&ASRoute
);
}
else
// Devices with no mike don't support PlayAndRecord - we don't get playback, so use just playback as we don't have a microphone anyway
[sharedSession setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
if (setCategoryError)
NSLog(@"Error setting audio category! %@", setCategoryError);
return muteSwitch;
}
使用環境模式用於播放視頻和PlayAndRecord模式記錄在相機屏幕上的視頻,解決了我們的情況的問題。
在應用程序的代碼中:didFinishLaunchingWithOptions:
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoRecording error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
上cameraController在viewWillAppear中的代碼,如果你必須使用相機或記錄在您的應用程序
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
上cameraController
在viewWillDisappear的代碼[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
使用這些行我們的應用程序r ecords並播放視頻和靜音開關在iOS8和iOS7下都可以完美工作!
如果我之後記錄環境的值,無論我是否靜音,我總是會返回1634558569。任何想法? – 2013-11-14 22:01:51
似乎無法在iOS 8上工作。 – 2015-06-12 19:55:46
「不行」如何?你做了什麼?你期望會發生什麼?反而發生了什麼?如果您提供更多信息,我會盡力更新我的答案。謝謝! – Olie 2015-06-13 01:30:31