I'm currently developing an app that requires detecting Bluetooth connections and disconnections in cars. During testing, I've observed the following behavior: In certain vehicles, only a Bluetooth connection via the car's hands-free system is available. In these cases, the device initiates a call to itself, which is then displayed on the vehicle's infotainment system.
In some of the tested vehicles, this self-call is brief and only occurs during the device's connection or disconnection process. However, in other vehicles, the self-call remains visible throughout the entire duration of the device's pairing with the car's Bluetooth system. This blocked call blocks the entire infotainment system and causes the connection/disconnection observers in my app to stop functioning as expected.
I'm looking for a solution or preventative measures to address this issue. Any guidance would be greatly appreciated.
Here is a snippet of my code:
`func audioSessionSetup() {
do {
resetAudioSession()
let audioOptions: AVAudioSession.CategoryOptions = [.duckOthers, .allowBluetooth, .defaultToSpeaker]
try audioSession.setCategory(.playAndRecord, mode: .spokenAudio, options: audioOptions)
registerNotifications()
try audioSession.setActive(true)
print("audioSession is active")
} catch let error as NSError {
print("Failed to set the audio audioSession category and mode: \(error.localizedDescription)")
}
}
/// Reset the audio session to deactivate it.
func resetAudioSession() {
do {
try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
} catch let error as NSError {
print("Failed to reset the audio audioSession, error: \(error.localizedDescription)")
}
}
@objc func handleRouteChange(_ notification: Notification) {
guard let userInfo = notification.userInfo,
let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {
return
}
switch reason {
case .newDeviceAvailable:
/// Handle new device connection
print("New device connected.")
checkConnectionForSelectedOutput(notification)
case .oldDeviceUnavailable:
/// Handle device disconnection
print("Device disconnected.")
handleLocationServices(state: false)
default:
print("break")
handleCategoryChange(notification)
break
}
}
private func handleCategoryChange(_ notification: Notification) {
if let connectedDeviceName = getConnectedBluetoothDeviceName() {
if connectedDeviceName != connectedDevice && connectedDeviceName == BluetoothUtils.getBluetoothInfo().portName {
connectedDevice = connectedDeviceName
checkConnectionForSelectedOutput(notification)
}
} else {
audioSessionSetup()
checkConnectionForSelectedOutput(notification)
print("handleRouteChange audio session is active")
}
}`