我的应用程序允许使用HFP(免提协议),因为它的#34;语音"提示(如导航应用程序)。
自从iOS 9.x开始,TextToSpeech或AVAudioPlayer之前的设置音频的功能如下所示。 我没有经常测试它是否经常运行PodCast所以我不确定什么时候会发生故障。如果音乐从电话流式传输到蓝牙A2DP或音乐正在汽车的FM收音机上播放(即它将中断收音机,提示和恢复收音机),则下面的功能非常有效。但如果我正在播放PodCast,它将无法运行。 PodCast暂停并出现提示静音,然后恢复PodCast。
我最近检查了Waze,Google地图和Apple地图(所有这些也都提供此HFP选项)。
Waze被打破了(但我不会经常对PodCast进行测试)。 谷歌地图仍然完美无缺。 Apple Maps很奇怪。流式传输时,HFP的选项显示为灰色。但是当它试图暂停和播放时它也会失败。
但同样,谷歌地图可以运作,所以可以做到。
当我使用HFP路由调用setPreferredInput时,如果PodCast正在流式传输,则不会调用我的路由更改处理程序(也如下所示)。如果音乐是Streaming我的路线更改处理程序被调用,而我的应用程序中的音频正确地来自HFP。
背景或前景并不重要。
任何有待解决的建议都将不胜感激。
func setupSound(_ activate: Bool)
{
if !Settings.sharedInstance.soundOn && !Settings.sharedInstance.voiceOn
{
return
}
var avopts:AVAudioSessionCategoryOptions = [
.mixWithOthers,
.duckOthers,
.interruptSpokenAudioAndMixWithOthers,
.allowBluetooth
]
if #available(iOS 10.0, *)
{
avopts.insert(AVAudioSessionCategoryOptions.allowBluetoothA2DP)
avopts.insert(AVAudioSessionCategoryOptions.allowAirPlay)
}
var HFP = false
if Settings.sharedInstance.HFPOn && callCenter.currentCalls == nil
{
do
{
if #available(iOS 10.0, *)
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeSpokenAudio, options: avopts)
}
else
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: avopts)
try AVAudioSession.sharedInstance().setMode(AVAudioSessionModeSpokenAudio)
}
}
catch
{
Settings.vprint("Failed Setup HFP Bluetooth Audio, ", error.localizedDescription)
}
if let inputs = AVAudioSession.sharedInstance().availableInputs
{
for route in inputs
{
if route.portType == AVAudioSessionPortBluetoothHFP
{
HFP = true
do
{
try AVAudioSession.sharedInstance().setPreferredInput(route)
HFP = true
break
}
catch
{
Settings.vprint("Failed Set Route HFP Bluetooth Audio, ", error.localizedDescription)
}
}
}
}
}
lastHFPStatus = HFP
if !HFP
{
var avopts:AVAudioSessionCategoryOptions = [
.mixWithOthers
]
if Settings.sharedInstance.duckingSoundOn
{
avopts.insert(.duckOthers)
avopts.insert(.interruptSpokenAudioAndMixWithOthers)
}
if Settings.sharedInstance.speakerOnlyOn
{
avopts.insert(.defaultToSpeaker)
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: avopts)
}
catch
{
Settings.vprint("Failed setCategory, ", error.localizedDescription)
}
}
else
{
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: avopts)
}
catch
{
Settings.vprint("Failed setCategory, ", error.localizedDescription)
}
}
}
do
{
try AVAudioSession.sharedInstance().setActive(activate, with: .notifyOthersOnDeactivation)
if ((Settings.sharedInstance.debugMask & 2) != 0)
{
Settings.vprint(activate)
}
}
catch
{
Settings.vprint("Could not setActive, ", error.localizedDescription)
}
}
@objc func handleRouteChange(notification: Notification)
{
Settings.vprint(notification)
let currentRoute = AVAudioSession.sharedInstance().currentRoute
for route in currentRoute.outputs
{
Settings.vprint("Change Output: ", route.portName)
}
for route in currentRoute.inputs
{
Settings.vprint("Change Input: ", route.portName)
}
}