web-dev-qa-db-fra.com

Routage audio vers un casque Bluetooth (non A2DP) sous Android

J'ai un casque à une oreille BT non-A2DP (Plantronics 510) et j'aimerais l'utiliser avec mon Android HTC Magic pour écouter du son de qualité médiocre, comme des podcasts/livres audio.

Après beaucoup de recherches sur Google, j'ai constaté que seul l'audio des appels téléphoniques peut être acheminé vers les casques BT non-A2DP. (J'aimerais savoir si vous avez trouvé une solution prête pour acheminer toutes sortes d'audio vers des casques BT non-A2DP)

J'ai donc pensé que, d'une manière ou d'une autre, je pouvais canaliser l'audio vers le flux qui transporte l'audio d'un appel téléphonique. De cette façon, je vais tromper le téléphone pour transférer mon mp3 au casque BT. J'ai écrit le code simple suivant.

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

Comme vous pouvez le constater, j'ai essayé différentes combinaisons de méthodes qui, selon moi, vont tromper le téléphone en lui faisant croire que mon audio est un appel téléphonique:

  • Utilisation de setAudioStreamType de MediaPlayer (STREAM_VOICE_CALL)
  • utilisation de setBluetoothScoOn (true) de AudioManager
  • en utilisant le setMode de AudioManager (MODE_IN_CALL)

Mais rien de ce qui précède n'a fonctionné. Si je supprime les appels AudioManager dans le code ci-dessus, l'audio est lu par le haut-parleur et si je les remplace comme indiqué ci-dessus, le son cesse de provenir des haut-parleurs, mais ne passe pas par le casque BT. Donc, cela pourrait être un succès partiel.

J'ai vérifié que le casque BT fonctionne correctement avec les appels téléphoniques.

Il doit y avoir une raison pour Android ne supportant pas cela. Mais je ne peux pas laisser tomber le sentiment qu'il n'est pas possible de réacheminer l'audio par programme. Des idées?

P.S. le code ci-dessus nécessite l'autorisation suivante 

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

38
Jayesh

Ce fil est peut-être mort depuis longtemps, mais pour ceux qui pourraient essayer la même chose, certaines notes de la documentation AudioManager peuvent être utiles. Il semble que l'élément manquant soit la commande startBluetoothSco (), mais il existe des restrictions quant à l'utilisation de ce canal. Depuis le site Android Dev ici :

public void startBluetoothSco () Depuis: API niveau 8 Démarrer bluetooth SCO connexion audio. 

Requiert la permission: MODIFY_AUDIO_SETTINGS. 

Cette méthode peut être utilisée par applications voulant envoyer et reçu de l’audio vers/depuis un SCO bluetooth casque lorsque le téléphone n’est pas allumé appel. 

En tant qu'établissement de connexion SCO peut prendre plusieurs secondes, les applications ne devrait pas compter sur la connexion à être disponible au retour de la méthode mais inscrivez-vous plutôt pour recevoir le intention ACTION_SCO_AUDIO_STATE_CHANGED et attendez que l'état soit SCO_AUDIO_STATE_CONNECTED. 

Comme la connexion n'est pas garantie à réussir, les applications doivent attendre cette intention avec un délai d'attente. 

Lorsque vous avez terminé avec la connexion SCO ou si l'établissement expire, le l'application doit appeler stopBluetoothSco () pour effacer le demander et désactiver le bluetooth lien. 

Même si une connexion SCO est établi, le suivant des restrictions s'appliquent à la sortie audio flux afin qu'ils puissent être acheminés vers Casque SCO: - le type de flux doit être STREAM_VOICE_CALL - le format doit être mono - l'échantillonnage doit être de 16 kHz ou 8kHz 

Les restrictions suivantes s'appliquent sur flux d'entrée: - le format doit être mono - l'échantillonnage doit être de 8 kHz 

Notez que l'application de téléphone toujours a la priorité sur l'utilisation du Connexion SCO pour la téléphonie. Si ce La méthode est appelée lorsque le téléphone est en appeler, il sera ignoré. De même, si un appel est reçu ou envoyé alors qu'un l'application utilise le SCO connexion, la connexion sera perdu pour l'application et PAS retourné automatiquement lorsque l'appel prend fin.

Voir aussi stopBluetoothSco () ACTION_SCO_AUDIO_STATE_CHANGED

Notez que je n'ai pas testé cela, je ne fais que transmettre une piste que j'ai trouvée dans la recherche d'un projet similaire. Je pense que Jayesh était proche de la solution et que les restrictions ci-dessus l'avaient peut-être empêché de fonctionner.

13
Vic

Pour allumer:

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

Éteindre:

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

Je l'ai pris d'ici

6
Uriel Frankel

Excellent travail cela fonctionne bien pour moi s'il vous plaît faire peu de modification dans votre code cela fonctionnera parfaitement i.e. 

mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 

to 

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
2
Aditya Hari Kishan

Un chemin de route ALSA doit être configuré pour le lecteur multimédia afin qu’il puisse ouvrir un autre chemin audio, puis acheminer votre audio vers le casque BT.

2
Arjuna

Ne peut pas voir une application de travail acceptée clairement acceptée, donc mettre une nouvelle réponse. Cette application route la musique et l'audio vers des casques Non A2dp. Essayez mon application et trouvez le code source également dans github pour le code de référence. https://github.com/sauravpradhan/AnySound2BT

0
Saurav