How can I play an Android TextToSpeech on the main speaker (where you hear calls) on the device?

2

I play the following code but it plays through the stereo speaker of the device:

private TextToSpeech textToSpeech = new TextToSpeech(this,this);

textToSpeech.setLanguage(new Locale("spa","ESP"));
speak("Hola mundo" );

private void speak(String str){
    AudioManager audioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
    audioManager.setMode(AudioManager.MODE_IN_CALL);
    audioManager.setSpeakerphoneOn(true);

    textToSpeech.speak(str,TextToSpeech.QUEUE_ADD,null);
    textToSpeech.setSpeechRate(0.0f);
    textToSpeech.setPitch(0.0f);
}

I want to do something similar to what happens when you try to play a sound on WhatsApp and you bring it close to your ear, it sounds through the device's call speaker.

    
asked by Antonio de los 11.05.2016 в 13:46
source

2 answers

1

In the end I was able to achieve it. First, you had to give him the necessary permits:

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

And then the code was the following:

AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
    audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
    audioManager.setSpeakerphoneOn(false);

    textToSpeech.setSpeechRate(1.0f);
    textToSpeech.setPitch(1.0f);
    textToSpeech.speak(str,TextToSpeech.QUEUE_FLUSH, null);
    
answered by 16.05.2016 / 17:44
source
-1

In order to invoke the setSpeakerphoneOn method you must have the necessary permissions in your manifest:

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

This has the problem that you are modifying the audio configuration and it will stay that way, unless you restore it to its previous value when you finish the playback.

  

I want to do something similar to what happens when you try to play a sound on WhatsApp and you bring it close to your ear, it sounds through the device's call speaker.

On the other hand ...

... for what you are trying to do, android has a mechanism that guarantees (or notifies you that it is not possible) that the audio will be played by the speaker (or headphones). This is done using the % method AudioManager.requestAudioFocus() with which you can capture some of the audio streams and play on it.

// Solicita el foco de audio para realizar una reproducción.
int result = am.requestAudioFocus(afChangeListener,
                             // usamos el stream para música (hay otros)
                             AudioManager.STREAM_ALARM,
                             // ver documentacion
                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);

if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    // preparas la reproducción. 
    textToSpeech.setSpeechRate(1.0f); // << esto es 1.0f
    textToSpeech.setPitch(1.0f);      // << 1.0f tambien

    // le indicas que use el stream de ALARM 
    textToSpeech.setAudioAttributes(new AudioAttributes.Builder()
         .setUsage(AudioAttributes.USAGE_ALARM)
         .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
         .build());

    // reproduces el text to speech.
    textToSpeech.speak(str,TextToSpeech.QUEUE_ADD, null);


    // al terminar
    am.abandonAudioFocus(...);
}

See more details here (in English)

    
answered by 11.05.2016 в 15:01