web-dev-qa-db-ja.com

AndroidでBluetoothヘッドセット(非A2DP)に音声をルーティングする

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"/>

40
Jayesh

このスレッドは長い間死んでいる可能性がありますが、同じことを試みている可能性のある人にとっては、AudioManager docsからのメモが役に立つかもしれません。欠落している要素はstartBluetoothSco()コマンドのようですが、このチャネルの使用には制限があります。 Android Dev site here から:

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でなければなりません-形式はモノラルでなければなりません-サンプリングは16kHzまたは8kHzでなければなりません

入力ストリームには次の制限が適用されます。-形式はモノラルでなければなりません-サンプリングは8kHzでなければなりません

電話アプリケーションは、電話のSCO接続の使用に常に優先順位を持っていることに注意してください。電話が通話中にこのメソッドが呼び出された場合、それは無視されます。アプリケーションがSCO接続を使用している間に受信または送信されると、アプリケーションの接続は失われ、通話の終了時に自動的に返されません。

関連項目stopBluetoothSco()ACTION_SCO_AUDIO_STATE_CHANGED

私はこれをテストしていないことに注意してください、私はちょうど私が同様のプロジェクトを研究する際に見つけたリードを渡しています。 Jayeshはソリューションに近づいており、上記の制限が動作を妨げていたのではないかと思います。

14
Vic

スイッチをつける:

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

ここから取りました

6
Uriel Frankel

それは私のためにうまく働いている素晴らしい仕事ですあなたのコードでビット修正をしてください.

mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 

to 

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
2

別のオーディオパスを開き、オーディオをBTヘッドセットにルーティングできるように、メディアプレーヤー用に設定されたALSAルートパスが必要です。

2
Arjuna

明確に受け入れられた有効なアプリケーションが表示されないため、新しい回答を入力します。このアプリケーションは、音楽とオーディオを非A2dpヘッドセットにルーティングします。私のアプリケーションを試してみて、参照コードについてもgithubでソースコードを見つけてください。 https://github.com/sauravpradhan/AnySound2BT

1
Saurav