Подтвердить что ты не робот

Маршрутизация аудио в Bluetooth-гарнитуру (не A2DP) на Android

У меня есть гарнитура для наушников с одним ухом без A2DP (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 не поддерживает это. Но я не могу отпустить ощущение, что невозможно программно перенаправить аудио. Любые идеи?

P.S. над кодом требуется следующее разрешение

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

4b9b3361

Ответ 1

Этот поток может быть длинным, но для тех, кто может попробовать одно и то же, некоторые примечания из документов AudioManager могут быть полезными. Похоже, что отсутствующим элементом является команда startBluetoothSco(), но есть ограничения на использование этого канала. С сайта Android Dev здесь:

public void startBluetoothSco() Начиная с: API уровня 8 Запустите bluetooth SCO   аудио соединение.

Требуется разрешение: MODIFY_AUDIO_SETTINGS.

Этот метод может быть использован приложений, желающих отправить и получил звук в/из Bluetooth SCO когда телефон не находится в вызов.

Как установление соединения SCO может занять несколько секунд, приложения не должны полагаться на соединение с быть доступным, когда метод возвращается но вместо этого зарегистрируйтесь, чтобы получить намерение ACTION_SCO_AUDIO_STATE_CHANGED и ждать, пока состояние будет SCO_AUDIO_STATE_CONNECTED.

Поскольку соединение не гарантируется преуспеть, приложения должны ждать это намерение с тайм-аутом.

По завершении соединения SCO или если время истечения срока приложение должно вызывать stopBluetoothSco(), чтобы очистить запросить и выключить Bluetooth подключение.

Даже если соединение SCO установлены следующие применяются ограничения на аудиовыход потоки, чтобы их можно было SCO-гарнитура: - тип потока должен быть STREAM_VOICE_CALL - формат должен быть моно - выборка должна быть 16 кГц или 8 кГц

Следующие ограничения применяются к входные потоки: - формат должен быть моно - выборка должна быть 8 кГц

Обратите внимание, что приложение телефона всегда имеет приоритет при использовании SCO для телефонии. Если это метод вызывается, когда телефон находится в вызов будет проигнорирован. Аналогично, если вызов принимается или отправляется, когда приложение использует SCO соединение, соединение будет потерянный для приложения и НЕ автоматически возвращается при вызове заканчивается.

См. также stopBluetoothSco() ACTION_SCO_AUDIO_STATE_CHANGED

Заметьте, что я не тестировал это, я просто передаю руководство, которое я нашел в исследовании аналогичного проекта. Я думаю, что Джайеш был близок к решению, и ограничения, наложенные выше, возможно, были тем, что удерживало его от работы.

Ответ 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);

Я взял его здесь

Ответ 3

Отличная работа, он отлично работает для меня, пожалуйста, сделайте бит-модификацию в своем коде, он будет отлично работать.

mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 

to 

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

Ответ 4

Для медиаплеера должен быть маршрут маршрута ALSA, чтобы он мог открыть другой аудиоканал, а затем направлять аудио в гарнитуру BT.

Ответ 5

Невозможно увидеть ясное принятое рабочее приложение, поэтому добавьте новый ответ. Это приложение направляет музыку и аудио в гарнитуры Non A2dp. Попробуйте мое приложение и найдите исходный код также в github для ссылочного кода. https://github.com/sauravpradhan/AnySound2BT