在Android上将音频路由到蓝牙耳机(非A2DP)

Jay*_*esh 41 audio android bluetooth

我有一个非A2DP单耳BT耳机(Plantronics 510),并希望与我的Android HTC Magic一起使用,以收听播客/有声读物等低质量音频.

经过大量的谷歌搜索,我发现只有电话呼叫音频可以路由到非A2DP BT耳机.(我想知道您是否找到了将各种音频路由到非A2DP BT耳机的现成解决方案)

所以我想,不知怎的,我可以通过编程方式将音频引导到携带电话音频的流.这样我就会欺骗手机将我的mp3音频传输到我的BT耳机.我写了以下简单的代码.

import android.content.*;
import android.app.Activity;
import android.os.Bundle;
import android.media.*;
import java.io.*;
import android.util.Log;

public class BTAudioActivity extends Activity
{
    private static final String TAG = "BTAudioActivity";

    private MediaPlayer mPlayer = null;
    private AudioManager amanager = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        amanager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        amanager.setBluetoothScoOn(true);
        amanager.setMode(AudioManager.MODE_IN_CALL);

        mPlayer = new MediaPlayer();

        try {
            mPlayer.setDataSource(new FileInputStream(
                "/sdcard/sample.mp3").getFD());

            mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);

            mPlayer.prepare();

            mPlayer.start();
        } catch(Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    @Override
    public void onDestroy()
    {
        mPlayer.stop();
        amanager.setMode(AudioManager.MODE_NORMAL);
        amanager.setBluetoothScoOn(false);
        super.onDestroy();
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以看到我尝试了各种方法的组合,我认为这会欺骗手机相信我的音频是一个电话:

  • 使用MediaPlayer的setAudioStreamType(STREAM_VOICE_CALL)
  • 使用AudioManager的setBluetoothScoOn(true)
  • 使用AudioManager的setMode(MODE_IN_CALL)

但以上都没有奏效.如果我在上面的代码中删除AudioManager呼叫,音频将从扬声器播放,如果我如上所示更换它们,那么音频将停止来自扬声器,但它不会通过BT耳机.所以这可能是部分成功.

我已经检查过BT耳机可以正常通话.

Android必须有理由不支持此功能.但是我不能放弃不可能以编程方式重新路由音频的感觉.有任何想法吗?

PS以上代码需要以下权限

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

Vic*_*Vic 14

这个帖子可能已经很久了,但对于那些可能尝试同样事情的人来说,AudioManager文档中的一些注释可能会很有用.看起来缺少的元素是startBluetoothSco()命令,但是对此通道的使用存在限制.从Android开发网站在这里:

public void startBluetoothSco()从:API Level 8启动蓝牙SCO音频连接.

需要权限:MODIFY_AUDIO_SETTINGS.

希望在电话未通话时向/从蓝牙SCO耳机发送和接收音频的应用程序可以使用此方法.

由于SCO连接建立可能需要几秒钟,因此应用程序不应依赖于方法返回时可用的连接,而是注册以接收意图ACTION_SCO_AUDIO_STATE_CHANGED并等待状态为SCO_AUDIO_STATE_CONNECTED.

由于无法保证连接成功,因此应用程序必须在超时时等待此意图.

完成SCO连接或建立超时后,应用程序必须调用stopBluetoothSco()来清除请求并关闭蓝牙连接.

即使建立了SCO连接,以下限制也适用于音频输出流,以便它们可以路由到SCO耳机: - 流类型必须为STREAM_VOICE_CALL - 格式必须为单声道 - 采样必须为16kHz或8kHz

以下限制适用于输入流: - 格式必须为单声道 - 采样必须为8kHz

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

另请参见stopBluetoothSco()ACTION_SCO_AUDIO_STATE_CHANGED

请注意,我没有对此进行过测试,我只是传递了我在研究类似项目时发现的一条线索.我认为Jayesh接近解决方案,上面的限制可能是阻止它工作的原因.


Uri*_*kel 7

打开:

 localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
 localAudioManager.setMode(0);
 localAudioManager.setBluetoothScoOn(true);
 localAudioManager.startBluetoothSco();
 localAudioManager.setMode(AudioManager.MODE_IN_CALL);
Run Code Online (Sandbox Code Playgroud)

把关掉:

 localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
 localAudioManager.setBluetoothScoOn(false);
 localAudioManager.stopBluetoothSco();
 localAudioManager.setMode(AudioManager.MODE_NORMAL);
Run Code Online (Sandbox Code Playgroud)

我从这里拿走了它


小智 2

应该为媒体播放器配置一条 ALSA 路由路径,以便它可以打开不同的音频路径,然后将您的音频路由到 BT 耳机。