40 votes

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

J'ai un non-A2DP seule oreille BT headset (Plantronics 510) et que vous souhaitez l'utiliser avec mon Android HTC Magic pour écouter de la faible qualité de l'audio comme des podcasts et livres audio.

Après beaucoup de recherches sur google, j'ai trouvé que seul appel téléphonique audio peuvent être acheminés à la non-A2DP BT casques. (Je voudrais savoir si vous avez trouvé une solution prête à acheminer tous les types de formats audio pour non-A2DP BT casques)

Alors j'ai pensé que, en quelque sorte, par programme, je peux le canal audio du ruisseau qui porte téléphone d'appel audio. De cette façon, je vais tromper le téléphone pour effectuer mon mp3 pour mon oreillette BT. J'ai écrit suivants du code simple.

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 voir j'ai essayé des combinaisons de différentes méthodes que je pensais va tromper le téléphone à en croire mes audio est un coup de téléphone:

  • Utilisation du lecteur multimédia de setAudioStreamType(STREAM_VOICE_CALL)
  • à l'aide de AudioManager de setBluetoothScoOn(vrai)
  • à l'aide de AudioManager de setMode(MODE_IN_CALL)

Mais aucun de ce qui précède travaillé. Si je supprime le AudioManager appels dans le code ci-dessus, la lecture audio de haut-parleur et si je les remplacer comme indiqué ci-dessus, alors l'audio s'arrête à venir de haut-parleurs, mais il ne vient pas à travers le BT casque. Donc cela pourrait être un succès partiel.

J'ai vérifié que le BT casque fonctionne très bien avec des appels téléphoniques.

Il doit y avoir une raison pour Android pas l'appui de cette. Mais je ne peux pas laisser aller le sentiment qu'il n'est pas possible par programmation de rediriger le audio. Des idées?

P. S. au-dessus de code d'autorisation suivantes

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

14voto

Vic Points 2129

Ce thread peut être mort depuis longtemps, mais pour ceux qui pourraient essayer de faire la même chose, quelques notes de la AudioManager docs peuvent être utiles. Il ressemble à l'élément manquant est la startBluetoothSco() la commande mais il y a des restrictions sur l'utilisation de ce canal. À partir de l'Android Dev site ici:

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

Nécessite Une Autorisation: MODIFY_AUDIO_SETTINGS.

Cette méthode peut être utilisée par des applications qui veulent envoyer et reçu audio/bluetooth SCO casque alors que le téléphone n'est pas dans appel.

Comme le SCO d'établissement de connexion peut prendre plusieurs secondes, les applications ne doivent pas compter sur la connexion à être disponible quand le retour de la méthode mais au lieu de vous inscrire pour recevoir la l'intention ACTION_SCO_AUDIO_STATE_CHANGED et d'attendre que l'etat SCO_AUDIO_STATE_CONNECTED.

Tant que la connexion n'est pas garantie réussir, les demandes doivent attendre cette intention avec un délai d'attente.

Lorsque vous avez terminé avec le SCO connexion ou, si l'établissement en temps, l' l'application doit appeler stopBluetoothSco() pour effacer le demande et baisser le bluetooth connexion.

Même si un SCO connexion est établi, les éléments suivants des restrictions s'appliquent sur la sortie audio cours d'eau afin qu'ils puissent être acheminés à SCO casque: - le type de flux de données doit être STREAM_VOICE_CALL - le format doit être mono - échantillonnage doit être 16kHz ou 8 khz

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

Notez que le téléphone demande toujours a la priorité sur l'utilisation de l' SCO connexion pour la téléphonie. Si ce la méthode est appelée lorsque le téléphone est en appel, elle sera ignorée. De même, si un appel est reçu ou envoyé tout un l'application est à l'aide de la SCO connexion, la connexion sera perdu pour l'application et ne PAS retourné automatiquement lors de l'appel se termine.

Voir Aussi stopBluetoothSco() ACTION_SCO_AUDIO_STATE_CHANGED

Notez que je n'ai pas testé, je suis juste de passage le long d'un plomb, j'ai trouvé en faisant des recherches sur un projet similaire. Je pense que Jayesh était proche de la solution et les restrictions ci-dessus peuvent avoir été ce qui était de l'empêcher de travailler.

6voto

Uriel Frankel Points 2143

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

2voto

Excellent travail cela fonctionne bien pour moi s'il vous plaît faire peu de modification dans votre code ça va marcher à-dire

 mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 

to 

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 

2voto

Arjuna Points 21

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

J'espère que tu as ce que j'ai dit

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X