首页 文章

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

提问于
浏览
38

我有一个非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();
    }
}

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

  • 使用MediaPlayer的setAudioStreamType(STREAM_VOICE_CALL)

  • 使用AudioManager的setBluetoothScoOn(true)

  • 使用AudioManager的setMode(MODE_IN_CALL)

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

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

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

附:以上代码需要以下权限

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

5 回答

  • 6

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

    public void startBluetoothSco()从:API Level 8启动蓝牙SCO音频连接 . 需要权限:MODIFY_AUDIO_SETTINGS . 希望在电话未通话时向/从蓝牙SCO耳机发送和接收音频的应用程序可以使用此方法 . 由于SCO连接 Build 可能需要几秒钟,因此应用程序不应依赖于方法返回时可用的连接,而是注册以接收意图ACTION_SCO_AUDIO_STATE_CHANGED并等待状态为SCO_AUDIO_STATE_CONNECTED . 由于无法保证连接成功,因此应用程序必须在超时时等待此意图 . 完成SCO连接或 Build 超时后,应用程序必须调用stopBluetoothSco()来清除请求并关闭蓝牙连接 . 即使 Build 了SCO连接,以下限制也适用于音频输出流,以便它们可以路由到SCO耳机: - 流类型必须为STREAM_VOICE_CALL - 格式必须为单声道 - 采样必须为16kHz或8kHz以下限制适用于输入流: - 格式必须为单声道 - 采样必须为8kHz请注意,电话应用程序始终优先使用SCO连接进行电话连接 . 如果在电话通话时调用此方法,则会忽略此方法 . 同样,如果在应用程序使用SCO连接时接收或发送呼叫,则应用程序的连接将丢失,并且在呼叫结束时不会自动返回 . 另请参见stopBluetoothSco()ACTION_SCO_AUDIO_STATE_CHANGED

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

  • 2

    打开:

    localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
     localAudioManager.setMode(0);
     localAudioManager.setBluetoothScoOn(true);
     localAudioManager.startBluetoothSco();
     localAudioManager.setMode(AudioManager.MODE_IN_CALL);
    

    把关掉:

    localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
     localAudioManager.setBluetoothScoOn(false);
     localAudioManager.stopBluetoothSco();
     localAudioManager.setMode(AudioManager.MODE_NORMAL);
    

    I took it from here

  • 2

    伟大的工作,它对我来说工作正常,请在您的代码中进行一些修改,它将完美地工作,即

    mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 
    
    to 
    
    mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    
  • 0

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

  • 13

    无法看到明确的已接受的工作申请,因此提出了新的答案 . 此应用程序将音乐和音频路由到非A2dp耳机 . 尝试我的应用程序,并在github中找到源代码以获取参考代码 . https://github.com/sauravpradhan/AnySound2BT

相关问题