In my project, I use AVAudioSession
to detect any headphone is plugged or unplugged. But in this case, I can't detect when bluetooth device is plugged. Here is my code for headphone state.
- (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");
[_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-on.png"] forState:UIControlStateNormal];
_headSetState=YES;
break;
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
NSLog(@"Headphone/Line was pulled. Stopping player....");
[_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-off.png"] forState:UIControlStateNormal];
if(_isPlaying==YES)
{
[self.player pause];
[_audioButtonOutlet setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
_isPlaying=NO;
}
_headSetState=NO;
break;
case AVAudioSessionRouteChangeReasonCategoryChange:
// called at start - also when other audio wants to play
NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
break;
}
- (BOOL)isHeadsetPluggedIn
{
AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance] currentRoute];
for (AVAudioSessionPortDescription* desc in [route outputs]) {
if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones])
{
[_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-on.png"] forState:UIControlStateNormal];
_headSetState=YES;
return YES;
}
else
{
[_soundButtonOutlet setImage:[UIImage imageNamed:@"sound-off.png"] forState:UIControlStateNormal];
_headSetState=NO;
return NO;
}
}
return NO;
}
}
- viewWillAppear {
[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];
[self isHeadsetPluggedIn];
}
So how can I detect if a bluetooth headset plugged or not iOS 8?
Simply open the “Find My” App on your iPhone and the app will show you the location of your connected devices. Bluetooth Scanner app. Will help you search for nearby Bluetooth devices, so you can narrow down your search area range.
Using a Bluetooth connection, you can use third-party devices such as wireless keyboards, headphones, speakers, car kits, game controllers, and more with iPhone. Note: iPhone must be within about 33 feet (10 meters) of the Bluetooth device.
If you're having trouble pairing headphones or a speaker that have been paired to many devices in the past, you may need to reset your headphones or speakers to clear out all of the pairings so you can start fresh. Search "reset" and your device name for instructions from the manufacturer on your specific model.
You can detect currently active bluetooth output devices (instead of input devices)
Swift Code:
import AVFoundation
func bluetoothAudioConnected() -> Bool{
let outputs = AVAudioSession.sharedInstance().currentRoute.outputs
for output in outputs{
if output.portType == AVAudioSessionPortBluetoothA2DP || output.portType == AVAudioSessionPortBluetoothHFP || output.portType == AVAudioSessionPortBluetoothLE{
return true
}
}
return false
}
Bluetooth devices are based on the following question: What's the difference among AVAudioSessionPortBluetoothHFP, A2DP and LE?
I hope it helps someone
Edit for Swift 5.1 (Thanks iago849 for the fix)
var bluetoothDeviceConnected: Bool {
!AVAudioSession.sharedInstance().currentRoute.outputs.compactMap {
($0.portType == .bluetoothA2DP ||
$0.portType == .bluetoothHFP ||
$0.portType == .bluetoothLE) ? true : nil
}.isEmpty
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With