forked from organicmaps/organicmaps
[android] Silence media volume while announcing navigation directions (#901)
* [android] Silenced media volume while announcing navigation directions. Signed-off-by: Dzmitry Yarmolenka <dzmitry.yarmolenka.1986@gmail.com> * [android] Changed AudioFocusManager according to project code style. Signed-off-by: Dzmitry Yarmolenka <dzmitry.yarmolenka.1986@gmail.com> * [android] Reduced delay after requesting audio focus to 50 milliseconds. Signed-off-by: Dzmitry Yarmolenka <dzmitry.yarmolenka.1986@gmail.com> * [android] removed small delay during requesting audio focus for cases, when background music is not playing. Signed-off-by: Dzmitry Yarmolenka <dzmitry.yarmolenka.1986@gmail.com>
This commit is contained in:
parent
3f12ad7dde
commit
959dc0834a
2 changed files with 81 additions and 3 deletions
51
android/src/com/mapswithme/maps/sound/AudioFocusManager.java
Normal file
51
android/src/com/mapswithme/maps/sound/AudioFocusManager.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
package com.mapswithme.maps.sound;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioFocusRequest;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import static android.media.AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
|
||||
|
||||
public class AudioFocusManager
|
||||
{
|
||||
@Nullable
|
||||
private AudioManager audioManager = null;
|
||||
|
||||
public AudioFocusManager(@Nullable Context context)
|
||||
{
|
||||
if (context != null)
|
||||
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
}
|
||||
|
||||
public boolean requestAudioFocus()
|
||||
{
|
||||
boolean isMusicActive = false;
|
||||
|
||||
if (audioManager != null)
|
||||
isMusicActive = audioManager.isMusicActive();
|
||||
|
||||
if (audioManager != null)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 26)
|
||||
audioManager.requestAudioFocus(new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE).build());
|
||||
else
|
||||
audioManager.requestAudioFocus(focusChange -> {}, AudioManager.STREAM_VOICE_CALL, AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE);
|
||||
}
|
||||
|
||||
return isMusicActive;
|
||||
}
|
||||
|
||||
public void releaseAudioFocus()
|
||||
{
|
||||
if (audioManager != null)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 26 )
|
||||
audioManager.abandonAudioFocusRequest(new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE).build());
|
||||
else
|
||||
audioManager.abandonAudioFocus(focusChange -> {});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,10 @@ package com.mapswithme.maps.sound;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.UtteranceProgressListener;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -44,9 +47,13 @@ public enum TtsPlayer implements Initializable<Context>
|
|||
private static final String TAG = TtsPlayer.class.getSimpleName();
|
||||
private static final Locale DEFAULT_LOCALE = Locale.US;
|
||||
private static final float SPEECH_RATE = 1.2f;
|
||||
private static final int TTS_SPEAK_DELAY_MILLIS = 50;
|
||||
|
||||
private TextToSpeech mTts;
|
||||
private boolean mInitializing;
|
||||
private AudioFocusManager mAudioFocusManager;
|
||||
|
||||
private final Handler delayHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
@SuppressWarnings("NotNullFieldNotInitialized")
|
||||
@NonNull
|
||||
|
@ -150,9 +157,25 @@ public enum TtsPlayer implements Initializable<Context>
|
|||
mInitializing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
refreshLanguages();
|
||||
mTts.setSpeechRate(SPEECH_RATE);
|
||||
mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
|
||||
@Override
|
||||
public void onStart(String utteranceId) {
|
||||
mAudioFocusManager.requestAudioFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone(String utteranceId) {
|
||||
mAudioFocusManager.releaseAudioFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String utteranceId) {
|
||||
mAudioFocusManager.releaseAudioFocus();
|
||||
}
|
||||
});
|
||||
mAudioFocusManager = new AudioFocusManager(context);
|
||||
mInitializing = false;
|
||||
});
|
||||
}
|
||||
|
@ -178,8 +201,11 @@ public enum TtsPlayer implements Initializable<Context>
|
|||
if (Config.isTtsEnabled())
|
||||
try
|
||||
{
|
||||
//noinspection deprecation
|
||||
mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, null);
|
||||
boolean isMusicActive = mAudioFocusManager.requestAudioFocus();
|
||||
if (isMusicActive)
|
||||
delayHandler.postDelayed(() -> mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, null, textToSpeak), TTS_SPEAK_DELAY_MILLIS);
|
||||
else
|
||||
mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, null, textToSpeak);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
|
@ -214,6 +240,7 @@ public enum TtsPlayer implements Initializable<Context>
|
|||
if (isReady())
|
||||
try
|
||||
{
|
||||
mAudioFocusManager.releaseAudioFocus();
|
||||
mTts.stop();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
|
|
Loading…
Add table
Reference in a new issue