it-swarm.com.de

Übertragen von Audio an ein Bluetooth-Headset (nicht A2DP) unter Android

Ich habe ein nicht-A2DP-BT-Headset mit einem Ohr (Plantronics 510) und möchte es zusammen mit meinem Android HTC Magic verwenden, um Audio in niedriger Qualität wie Podcasts/Hörbücher zu hören.

Nach vielem googeln habe ich festgestellt, dass nur Anruf-Audio zu den Nicht-A2DP-BT-Headsets geleitet werden kann. (Ich würde gerne wissen, ob Sie eine geeignete Lösung gefunden haben, um alle Arten von Audiodaten an Nicht-A2DP-BT-Headsets weiterzuleiten.)

Also dachte ich mir, irgendwie kann ich das Audio programmgesteuert auf den Stream leiten, der Telefonanrufe überträgt. Auf diese Weise werde ich das Telefon täuschen, um mein MP3-Audio auf mein BT-Headset zu übertragen. Ich habe folgenden einfachen Code geschrieben.

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

Wie Sie sehen, habe ich Kombinationen verschiedener Methoden ausprobiert, von denen ich dachte, dass sie das Telefon täuschen werden, um zu glauben, dass mein Ton ein Anruf ist:

  • SetAudioStreamType von MediaPlayer verwenden (STREAM_VOICE_CALL)
  • verwenden des AudioManagers setBluetoothScoOn (true)
  • verwenden des setManager von AudioManager (MODE_IN_CALL)

Aber nichts davon funktionierte. Wenn ich die AudioManager-Anrufe im obigen Code entferne, wird das Audio vom Lautsprecher abgespielt. Wenn ich sie wie oben gezeigt austausche, wird das Audio nicht mehr von den Lautsprechern gesendet, aber es kommt nicht über das BT-Headset. Das könnte also ein Teilerfolg sein.

Ich habe überprüft, ob das BT-Headset bei Anrufen in Ordnung ist.

Es muss einen Grund geben, warum Android dies nicht unterstützt. Ich kann jedoch nicht das Gefühl loslassen, dass es nicht möglich ist, das Audio programmatisch umzuleiten. Irgendwelche Ideen?

P.S. Code oben benötigt folgende Erlaubnis 

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

38
Jayesh

Dieser Thread ist zwar schon lange tot, aber für diejenigen, die dasselbe versuchen, können einige Anmerkungen aus den AudioManager-Dokumenten nützlich sein. Anscheinend ist das fehlende Element der Befehl startBluetoothSco (), es gibt jedoch Einschränkungen bei der Verwendung dieses Kanals. Von der Android Dev Site hier :

public void startBluetoothSco () Seit: API Level 8 Starten Sie Bluetooth SCO Audio-Verbindung. 

Erfordert Erlaubnis: MODIFY_AUDIO_SETTINGS. 

Diese Methode kann von .__ verwendet werden. Anwendungen, die senden möchten und empfangenes Audio zu/von einem Bluetooth-SCO Headset, wenn sich das Telefon nicht in .__ befindet. Anruf. 

Als SCO Verbindungsaufbau kann einige Sekunden dauern, Anwendungen sollte sich nicht auf die Verbindung zu .__ verlassen. verfügbar sein, wenn die Methode zurückgegeben wird Melden Sie sich stattdessen für den Erhalt der Vorsatz ACTION_SCO_AUDIO_STATE_CHANGED und warten Sie, bis der Staat .__ ist. SCO_AUDIO_STATE_CONNECTED. 

Da die Verbindung nicht garantiert ist erfolgreich, Anwendungen müssen warten auf diese Absicht mit einem Timeout. 

Wenn Sie mit der Verbindung SCO fertig sind, __. oder wenn die Einrichtung abläuft, der Anwendung muss aufrufen stopBluetoothSco (), um die .__ zu löschen. fordern Sie an und schalten Sie das Bluetooth aus Verbindung. 

Auch wenn eine SCO -Verbindung .__ ist. festgestellt, die folgenden Einschränkungen gelten für die Audioausgabe Streams, damit sie zu .__ geleitet werden können. SCO headset: - Der Stream-Typ muss .__ sein. STREAM_VOICE_CALL - Das Format muss .__ sein. Mono - die Abtastung muss 16 kHz oder .__ sein. 8kHz 

Die folgenden Einschränkungen gelten für Eingabeströme: - Das Format muss .__ sein. Mono - die Abtastung muss 8 kHz sein 

Beachten Sie, dass die Telefonanwendung immer hat die Priorität auf die Verwendung von SCO Verbindung für die Telefonie. Wenn dies Die Methode wird aufgerufen, während sich das Telefon in .__ befindet. Aufruf wird ignoriert. Ebenso, wenn Ein Anruf wird empfangen oder gesendet, während ein Anwendung verwendet das SCO Verbindung wird die Verbindung .__ sein. verloren für die Anwendung und NICHT automatisch zurückgegeben, wenn der Anruf endet.

Siehe auch stopBluetoothSco () ACTION_SCO_AUDIO_STATE_CHANGED

Beachten Sie, dass ich dies nicht getestet habe. Ich gebe nur einen Hinweis weiter, den ich bei der Erforschung eines ähnlichen Projekts gefunden habe. Ich glaube, Jayesh war der Lösung nahe und die oben genannten Einschränkungen waren möglicherweise das, was die Arbeit davon abhielt.

13
Vic

Zum Einschalten:

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

Ausschalten:

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

ich habe es von hier genommen

6
Uriel Frankel

Großartige Arbeit, es funktioniert gut für mich, bitte machen Sie ein bisschen Änderung in Ihrem Code, es wird perfekt funktionieren, d. H. 

mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 

to 

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
2

Für den Mediaplayer sollte ein ALSA-Routenpfad konfiguriert sein, damit er einen anderen Audiopfad öffnen und das Audiomaterial dann an das BT-Headset weiterleiten kann.

2
Arjuna

Es wird keine eindeutige akzeptierte Arbeitsanwendung angezeigt, sodass eine neue Antwort eingegeben wird. Diese Anwendung leitet Musik und Audio an Nicht-A2dp-Headsets weiter. Probieren Sie meine Anwendung aus und finden Sie den Quellcode auch in github für Referenzcode. https://github.com/sauravpradhan/AnySound2BT

0
Saurav