Android: воспроизведение звука через гарнитуру Sco Bluetooth - PullRequest
6 голосов
/ 27 августа 2011

Последние несколько дней я пытался воспроизвести любой звук через мою sco bluetooth-гарнитуру с моего телефона Android. Моя конечная цель в этом проекте - в конечном итоге сделать устройство для открывания гаражных ворот, но сначала я должен уметь воспроизводить звук через гарнитуру.

Вот основа текущего кода, который я использую:

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

Перед запуском я подключаю свою гарнитуру Bluetooth к своему телефону и подключаю ее. Я подтвердил, что это работает, позвонив в мою голосовую почту. Однако, когда я запускаю свой код, нигде не слышен звук.

Вот эффекты различных строк кода:

Когда я просто запускаю свое приложение:

    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 ]

1 голос
/ 05 июля 2012

Я нашел решение на этой странице . Вы должны звонить audioManager.setMode(AudioManager.MODE_IN_CALL); только после того, как сокет подключен, т.е. вы получили AudioManager.SCO_AUDIO_STATE_CONNECTED. Я мог слышать TTS на моем Android Spica работает 2.2.2.

Edit: Вот моя (старая) реализация:

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.

0 голосов
/ 09 марта 2012

Добавить в манифест:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
0 голосов
/ 30 марта 2012

Мне действительно удалось это исправить. Проблема заключалась в том, что моя высота, которую я играл через гарнитуру, была слишком высокой частоты. Я исправил это, просто удвоив код, который создает аудиофайл, чтобы он стал HIGH HIGH LOW LOW вместо HIGH LOW HIGH LOW.

0 голосов
/ 07 февраля 2012

Попробуйте установить для audiomanager значение AudioManager.MODE_NORMAL.Тос работал на меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...