我似乎无法在SDK中找到如何以编程方式感知iPhone上的静音按钮/开关.当我的应用程序播放背景音乐时,它会正确响应音量按钮,而我没有任何代码可以遵循,但是,当我使用静音开关时,它只是继续播放.
如何测试静音的位置?
(注意:我的程序有自己的静音开关,但我希望物理开关覆盖它.)
谢谢!
谢谢,JPM.实际上,你提供的链接会得到正确的答案(最终.;)为了完整性(因为SO应该是QUICK答案的来源!)......
// "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."); }
我在这里回答了类似的问题(链接).相关代码:
-(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; }
为了找出静音开关和音量控制的状态,我写了这两个函数.如果您希望在尝试创建音频输出之前警告用户,这些是理想的选择.
-(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); }