2008-11-13 63 views
39

我似乎無法在SDK中找到如何以編程方式感知iPhone上的靜音按鈕/開關。當我的應用程序播放背景音樂時,它會正確響應音量按鈕,而我沒有任何代碼可以遵循,但是,當我使用靜音開關時,它只會繼續播放。如何以編程方式感應iPhone靜音開關?

如何測試靜音的位置?

(注:我的程序有自己的靜音開關,但我想在物理交換機來覆蓋。)

謝謝!

回答

29

謝謝,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."); 
} 
+0

如果我之後記錄環境的值,無論我是否靜音,我總是會返回1634558569。任何想法? – 2013-11-14 22:01:51

+0

似乎無法在iOS 8上工作。 – 2015-06-12 19:55:46

+0

「不行」如何?你做了什麼?你期望會發生什麼?反而發生了什麼?如果您提供更多信息,我會盡力更新我的答案。謝謝! – Olie 2015-06-13 01:30:31

5

OLIE,

我相信你可以找到答案,你的問題在這裏:

https://devforums.apple.com/message/1135#1135

我假設你可以訪問開發者論壇在Apple.com :)

+0

Sho''nuff! 快速回顧:「AudioSessionSetProperty將AudioCategory設置爲Ambient」(我相信可以談論發貨軟件......) 謝謝! – Olie 2008-11-15 07:42:11

4

我這裏遵循的一般理論,得到了這個工作 http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/

這裏有一個概括:播放一小段沉默的聲音。時間需要多長時間才能播放。如果靜音開關打開,聲音的播放將比聲音本身短得多。我使用了500ms的聲音,如果聲音播放時間少於此時間,則靜音開關打開。我使用音頻服務來播放無聲的聲音(始終尊重靜音開關)。本文說您可以使用AVAudioPlayer播放此聲音。如果您使用AVAudioPlayer,我假設您需要設置您的AVAudioSession類別以遵守靜音開關,但我沒有嘗試過。

5

要了解靜音開關的音量控制狀態,我寫了這兩個函數。如果您希望在嘗試創建音頻輸出之前警告用戶,這些都是理想之選。

-(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; 
} 
5
-(BOOL)isDeviceMuted 
{ 
CFStringRef state; 
UInt32 propertySize = sizeof(CFStringRef); 
AudioSessionInitialize(NULL, NULL, NULL, NULL); 
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state); 
return (CFStringGetLength(state) > 0 ? NO : YES); 
} 
10

我回答了類似的問題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; 

    } 
7

一些在其他的答案(包括接受的答案)的代碼,如果你不是在環境模式,在靜音開關的尊重可能無法正常工作。

我寫下例程切換到環境,閱讀開關,然後返回到我的應用程序需要的設置。

-(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; 
} 
3

使用環境模式用於播放視頻和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下都可以完美工作!

相關問題