3

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

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

我可以看到 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 模式下,所有的流都被定向到手机扬声器,这里没有安卓系统提供改变模式的方法。

4

3 回答 3

0

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

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

在主要活动中,在创建时初始化:

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);

这也没有用。

于 2013-04-17T14:25:57.650 回答
0

我认为媒体播放器会在电话响铃时释放蓝牙连接。您可以尝试获取蓝牙音频连接,看看媒体播放器现在是否通过您获得的连接播放。您可以在我的回答中使用我的课程Using the Android RecognizerIntent with a bluetooth耳机,看看它是否有效。课堂上的音频只有 Sco。

于 2013-04-13T23:31:22.223 回答
0

如 StartBluetoothSco 方法的 JavaDoc 中所述:

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

我尝试启动 sco,然后在正常模式下播放音乐剪辑,它可以毫无问题地播放到蓝牙耳机,尽管我无法停止导致输入流播放到耳机的麦克风。然后我尝试在音乐仍在播放时从另一部手机拨打我的目标手机,我发现流已自动重定向到手机扬声器。振铃模式结束后,流并没有再次重定向到蓝牙耳机,我认为根据上面的 JavaDoc 中所述的行为是正常的。

我的猜测是,Android 会尽可能保护振铃和通话模式,以免应用程序产生任何不必要的干扰。换句话说,当处于振铃模式时,在接听电话之前不会向耳机播放任何声音,并且您甚至无法将 AudioManager 模式从振铃模式更改为另一种模式,您的模式设置器呼叫将被忽略。

于 2013-04-16T20:07:49.650 回答