耳机是否插入? IOS 7
开发一个iPhone应用程序,audio文件也需要通过耳机收听。
如何检查耳机是否插入,以便我可以告诉用户插入耳机。
我从另一个线程有以下代码,但audioSessionGetProperty方法已被弃用。 任何人都知道如何改变下面的代码来使这个工作或有自己的代码/解决scheme。
谢谢。
- (BOOL)isHeadsetPluggedIn { UInt32 routeSize = sizeof (CFStringRef); CFStringRef route; //Maybe changing it to something like the following would work for iOS7? //AVAudioSession* session = [AVAudioSession sharedInstance]; //OSStatus error = [session setCategory:kAudioSessionProperty_AudioRoute...? //the line below is whats giving me the warning OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, &routeSize, &route); /* Known values of route: * "Headset" * "Headphone" * "Speaker" * "SpeakerAndMicrophone" * "HeadphonesAndMicrophone" * "HeadsetInOut" * "ReceiverAndMicrophone" * "Lineout" */ if (!error && (route != NULL)) { NSString* routeStr = (__bridge NSString*)route; NSRange headphoneRange = [routeStr rangeOfString : @"Head"]; if (headphoneRange.location != NSNotFound) return YES; } return NO; }
这应该可行,但我现在不能testing,我会在晚上做。
- (BOOL)isHeadsetPluggedIn { AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance] currentRoute]; for (AVAudioSessionPortDescription* desc in [route outputs]) { if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones]) return YES; } return NO; }
只是扩大@安东尼奥的答案。 如果您需要检测用户是否拔出或插入耳机。
#import <AVFoundation/AVFoundation.h>
// [AVAudioSession sharedInstance]; // @Boris edited: you may need it if there is no `AVAudioSession instance` created before. If doesn't work, uncomment this line. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil]; // don't forget to `removeObserver:`
// If the user pulls out he headphone jack, stop playing. - (void)audioRouteChangeListenerCallback:(NSNotification*)notification { NSDictionary *interuptionDict = notification.userInfo; NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; switch (routeChangeReason) { case AVAudioSessionRouteChangeReasonNewDeviceAvailable: NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable"); NSLog(@"Headphone/Line plugged in"); break; case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable"); NSLog(@"Headphone/Line was pulled. Stopping player...."); break; case AVAudioSessionRouteChangeReasonCategoryChange: // called at start - also when other audio wants to play NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange"); break; } }
@ Swift 2.0中的 Warif代码,几乎没有什么变化
func audioRouteChangeListenerCallback (notif: NSNotification){ let userInfo:[NSObject:AnyObject] = notif.userInfo! println("\(userInfo)") let routChangeReason = UInt((userInfo[AVAudioSessionRouteChangeReasonKey]?.integerValue)!) switch routChangeReason { case AVAudioSessionRouteChangeReason.NewDeviceAvailable.rawValue: self.println("Headphone/Line plugged in"); break; case AVAudioSessionRouteChangeReason.OldDeviceUnavailable.rawValue: //If the headphones was pulled move to speaker do { try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.Speaker) } catch _ { } self.println("Headphone/Line was pulled. Stopping player...."); break; case AVAudioSessionRouteChangeReason.CategoryChange.rawValue: // called at start - also when other audio wants to play self.println("AVAudioSessionRouteChangeReasonCategoryChange"); break; default: break; } }
:d
Swift 3:
检查是否连接了耳机
extension AVAudioSession { static var isHeadphonesConnected: Bool { return sharedInstance().isHeadphonesConnected } var isHeadphonesConnected: Bool { return !currentRoute.outputs.filter { $0.isHeadphones }.isEmpty } } extension AVAudioSessionPortDescription { var isHeadphones: Bool { return portType == AVAudioSessionPortHeadphones } }
然后你可以print("isHeadphones connected: \(AVAudioSession.isHeadphonesConnected)")
聆听变化
在Swift 3中 ,语法是这样的:
func handleRouteChange(_ notification: Notification) { guard let userInfo = notification.userInfo, let reasonRaw = userInfo[AVAudioSessionRouteChangeReasonKey] as? NSNumber, let reason = AVAudioSessionRouteChangeReason(rawValue: reasonRaw.uintValue) else { fatalError("Strange... could not get routeChange") } switch reason { case .oldDeviceUnavailable: print("oldDeviceUnavailable") case .newDeviceAvailable: print("newDeviceAvailable") if AVAudioSession.isHeadphonesConnected { print("Just connected headphones") } case .routeConfigurationChange: print("routeConfigurationChange") case .categoryChange: print("categoryChange") default: print("not handling reason") } } func listenForNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: NSNotification.Name.AVAudioSessionRouteChange, object: nil) }
注意使用:
if AVAudioSession.isHeadphonesConnected { print("Just connected headphones") }
在Swift(截至1.2):
func headsetPluggedIn() -> Bool { let route = AVAudioSession.sharedInstance().currentRoute return (route.outputs as! [AVAudioSessionPortDescription]).filter({ $0.portType == AVAudioSessionPortHeadphones }).count > 0 }
Swift 3.0版本
- 检查是否插入了耳机或连接了audio输出的任何蓝牙设备的方法
func bluetoothOrHeadphonesConnected() - > Bool { 让outputs = AVAudioSession.sharedInstance()。currentRoute.outputs 用于输出{ 如果output.portType == AVAudioSessionPortBluetoothA2DP || output.portType == AVAudioSessionPortBluetoothHFP || output.portType == AVAudioSessionPortBluetoothLE || output.portType == AVAudioSessionPortHeadphones { 返回true } } 返回false }
- 在收听任何audio时,检查耳机是否拔出很重要。
私人func setupObservers(){ NotificationCenter.default.addObserver(self,selector:#selector(self.audioRouteChangeListener),name:.AVAudioSessionRouteChange,object:nil) } func audioRouteChangeListener(通知:通知){ 后卫let audioRouteChangeReason = notification.userInfo![AVAudioSessionRouteChangeReasonKey] as? 诠释其他{返回} 切换audioRouteChangeReason { 案例AVAudioSessionRouteChangeReason.oldDeviceUnavailable.hashValue: //堵塞了 默认: 打破 } }
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(plugout:) name:AVAudioSessionRouteChangeNotification object:nil]; -(void)plugout:(NSNotification*)notification { isRemovedHeadset = YES; }
并使用这个isRemovedHeadset布尔值处理你的代码
if (moviePlayer.playbackState == MPMoviePlaybackStatePaused) { if(isRemovedHeadset) { isRemovedHeadset = NO; [moviePlayer prepareToPlay]; [moviePlayer play]; return; } }