响铃时将音频路由到蓝牙A2DP设备[Android]

时间:2013-04-13 23:15:53

标签: android

我正在尝试确定如何将非常短的音频流(通知)路由到已与设备配对的蓝牙耳机,同时设备正在振铃。

当我随时播放任何音频时,它会被路由到蓝牙设备,没问题。 但是如果我在接收到android.intent.action.PHONE_STATE时尝试开始播放音频,则在RINGING状态下,音频不会按预期路由。

我可以看到AudioManager的setBluetoothA2dpOn方法已经被弃用了,但我实际上已经尝试过了,但似乎没有效果。

我已经尝试了MediaRouter对象,但我可以看到MediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_AUDIO)在设备振铃时指向蓝牙设备的RouteInfo,而AudioManager.isBluetoothA2dpOn为真。

那么,任何人都可以告诉我为什么音频路线在振铃时刻是这样的吗?有没有办法强制音频在这种情况下路由到蓝牙设备?

[增订] 我今天再次尝试,我发现了可能导致问题的原因。 我创建了一个BroadcaseReceiver来检测android.intent.action.PHONE_STATE中的更改。如果收到意图并且状态当前正在振铃,请检查AudioManager的模式,您会发现它是MODE_NORMAL。但几秒钟后,手机将开始实际振铃,模式将变为MODE_RINGTONE。尝试使用方法setMode(AudioManager.MODE_NORMAL)手动设置模式是没用的,即使将状态设置为MODE_NORMAL后状态仍为MODE_RINGTONE。

现在,我认为问题的原因是在MODE_RINGTONE模式下,所有的流都被定向到手机扬声器,这里安卓系统无法改变模式。

3 个答案:

答案 0 :(得分:0)

我认为媒体播放器会在手机响铃时重新启动蓝牙连接。您可以尝试获取蓝牙音频连接,并查看媒体播放器现在是否通过您获得的连接播放。您可以在我的回答Using the Android RecognizerIntent with a bluetooth headset上使用我的课程,看看它是否有效。该类中的音频仅为Sco。

答案 1 :(得分:0)

正如StartDluetoothSco方法的JavaDoc中所述:

  

请注意,电话应用程序始终优先使用SCO连接进行电话连接。如果在电话通话时调用此方法,则会忽略此方法。同样,如果在应用程序使用SCO连接时收到或发送了一个呼叫,则该应用程序的连接将丢失,并且在呼叫结束时不会自动返回。`

我尝试启动sco然后在正常模式下播放音乐片段,它播放到蓝牙耳机没有问题,虽然我无法阻止导致输入流播放到耳机的麦克风。然后,当音乐仍在播放时,我尝试从另一部手机拨打目标手机,我发现该流已自动重定向到手机扬声器。振铃模式完成后,流不再被重定向到蓝牙耳机,我认为根据上面的JavaDoc中的说明,这种行为是正常的。
我的猜测是Android试图尽可能保护振铃和通话模式,以免给应用程序带来任何不必要的干扰。换句话说,当处于振铃模式时,在接受呼叫之前不会向耳机播放声音,并且您甚至无法将振铃管理器模式从振铃更改为其他模式,您的模式设置器调用将被忽略。

答案 2 :(得分:0)

我已经尝试过AudioTrack而不是MediaPlayer,但这没什么区别。

然后我尝试了这样的TextToSpeech引擎:

在主要活动中,在create:

上初始化
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textToSpeech=new TextToSpeech(this, this);
    textToSpeech.setLanguage(Locale.US);
    textToSpeech.addEarcon("[wwww]", "XXXXXXXXXXXXXXXXXXXXXXX", R.raw.a);
}

在广播接收器类中,当启动蓝牙实用程序类并将以下内容添加到onScoAudioConnected方法时

textToSpeech.playEarcon("[wwww]", TextToSpeech.QUEUE_FLUSH, null);

这也不起作用。