Android:通过Sco蓝牙耳机播放声音

时间:2011-08-27 06:03:09

标签: java android audio bluetooth

在过去的几天里,我一直试图从我的Android手机上播放我的sco蓝牙耳机上的任何声音。我这个项目的最终目标是最终制作一个车库门开启器,但首先我需要能够通过耳机播放声音。

以下是我正在使用的当前代码的基础:

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


==Code==
    audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

    audioManager.setMode(AudioManager.MODE_IN_CALL);
    audioManager.startBluetoothSco();
    audioManager.setBluetoothScoOn(true);

    short[] soundData = new short [8000*20];
    for (int iii = 0; iii < 20*8000; iii++) {
        soundData[iii] = 32767;
        iii++;
        soundData[iii] = -32768;
    }

    audioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
            8000, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, soundData.length
            * Short.SIZE, AudioTrack.MODE_STATIC);
    audioTrack.write(soundData, 0, soundData.length);
    audioTrack.play();

在我运行之前,我将蓝牙耳机与手机配对并连接好。我通过调用我的语音邮件验证了它的工作原理。然而,当我运行我的代码时,任何地方都没有声音。

以下是不同代码行的效果:

当我刚刚运行我的应用时:

    audioManager.setMode(AudioManager.MODE_IN_CALL);

这条线让我的所有声音都停止工作,无论我做什么,所以它通常被注释掉。

    audioManager.startBluetoothSco();
    audioManager.setBluetoothScoOn(true);

这两条线让声音从前置扬声器中消失,使我的耳机发出咔嗒声,嘶嘶声就像它已经打开但是没有输出。

AudioManager.STREAM_VOICE_CALL

这是我对AudioTrack构造函数的调用的一部分,但它有很大的不同。由于设置为STREAM_VOICE_CALL,声音从前置扬声器发出,如果我将其设置为STREAM_MUSIC,则声音会从后置扬声器发出。

在通话期间打开我的应用时:

    audioManager.setMode(AudioManager.MODE_IN_CALL);

在通话期间,此行无效,因为已设置MODE_IN_CALL。但不同的是,我的声音与电话混合在一​​起,而通常它根本不播放。

    audioManager.startBluetoothSco();
    audioManager.setBluetoothScoOn(true);

这些对应的一半可以控制音频的来源。如果我把它关掉,我的声音和电话都来自前置扬声器,打开后,电话就会来自我的耳机,我的声音就会丢失。

至于为什么我的代码不起作用,老实说我不知道​​。我相信我已经完成了使用startBluetoothSco()的清单。

Even if a SCO connection is established, the following restrictions 
apply on audio output streams so that they can be routed to SCO headset: 
- the stream type must be STREAM_VOICE_CALL - the format must be mono - 
the sampling must be 16kHz or 8kHz

那么,有没有人知道我做错了什么?曾经有一次我设法让我的声音通过耳机播放,但是当我忘记停止()我的AudioTrack时,它只是一个短音,所以我不得不认为这是一个小故障。

4 个答案:

答案 0 :(得分:1)

我在page找到了解决方案。 只有在连接套接字后,您才需要呼叫audioManager.setMode(AudioManager.MODE_IN_CALL);,即您收到AudioManager.SCO_AUDIO_STATE_CONNECTED。我能在运行Android 2.2.2的Spica上听到TTS。

编辑: 这是我的(旧)实现:

public class BluetoothNotificationReceiver
extends BroadcastReceiver
{   

    /**
     * 
     */
    public BluetoothNotificationReceiver(Handler h)
    {
        super();
        bnrHandler = h;
    }

    /* (non-Javadoc)
     * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
     */
    @Override
    public void onReceive(Context arg0, Intent arg1)
    {
        String action = arg1.getAction();
        if (action.equalsIgnoreCase(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED))
        {
            int l_state = arg1.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
            Log.d("bnr", "Audio SCO: " + AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
            switch(l_state)
            {
            case AudioManager.SCO_AUDIO_STATE_CONNECTED:
            { 
                Log.i("bnr", "SCO_AUDIO_STATE_CONNECTED");
            }
            break;
            case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
                { 
                    Log.e("bnr", "SCO_AUDIO_STATE_DISCONNECTED");                   
                }
            break;
            default: Log.e("bnr", "unknown state received:"+l_state);
            }
        }
        else
            Log.e("bnr", "onReceive:action="+action);
    }
}

我不知道它是否仍在使用新的API。

答案 1 :(得分:0)

尝试将audiomanager设置为AudioManager.MODE_NORMAL。这对我有用。

答案 2 :(得分:0)

添加到清单:

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

答案 3 :(得分:0)

我确实设法解决了这个问题。问题是我在耳机上播放的音调太高了。我通过简单地加倍创建音频文件的代码来修复它,使其变为HIGH HIGH LOW LOW而不是HIGH LOW HIGH LOW。

相关问题