我在STREAM_RING
之前保存当前音量STREAM_MUSIC
和sTts.get().speak(s, TextToSpeech.QUEUE_ADD, null)
,我希望TextToSpeech
能说出最大音量的文字,
但事实上我发现TextToSpeech
用当前音量说出文本,似乎sTts.get().speak
是异步的。
如何让TextToSpeech
说出最大音量的文字并在讲话结束后恢复原始音量?谢谢!
public class SpeechTxt {
private static SoftReference<TextToSpeech> sTts;
public static void SpeakOut(final Context context, final String s) {
final Context appContext = context.getApplicationContext();
if (sTts == null) {
sTts = new SoftReference<TextToSpeech>(new TextToSpeech(appContext,
new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
speak(appContext, s);
} else {
}
}
}));
} else {
speak(appContext, s);
}
}
private static void speak(Context context, String s) {
if (sTts != null) {
switch (sTts.get().setLanguage(Locale.getDefault())) {
case TextToSpeech.LANG_COUNTRY_AVAILABLE:
case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
case TextToSpeech.LANG_AVAILABLE: {
sTts.get().setPitch((float) 0.6);
sTts.get().setSpeechRate((float) 0.8);
int currentRing=PublicParFun.GetCurrentVol(context, AudioManager.STREAM_RING);
int currentPlay=PublicParFun.GetCurrentVol(context, AudioManager.STREAM_MUSIC);
PublicParFun.SetRingVol(context, 0);
PublicParFun.SetPlayVol(context,1000000);
sTts.get().speak(s, TextToSpeech.QUEUE_ADD, null);
PublicParFun.SetRingVol(context, currentRing);
PublicParFun.SetPlayVol(context,currentPlay);
break;
}
case TextToSpeech.LANG_MISSING_DATA: {
break;
}
case TextToSpeech.LANG_NOT_SUPPORTED: // not much to do here
}
}
}
public static int GetCurrentVol(Context myContext,int streamType){
AudioManager mAudioManager = (AudioManager)myContext.getSystemService(Context.AUDIO_SERVICE);
int current = mAudioManager.getStreamVolume( streamType);
return current;
}
public static void SetRingVol(Context myContext,int vol){
SetVol(myContext,AudioManager.STREAM_RING, vol);
}
public static void SetPlayVol(Context myContext,int vol){
SetVol(myContext,AudioManager.STREAM_MUSIC, vol);
}
private static void SetVol(Context myContext,int streamType,int vol){
AudioManager mAudioManager = (AudioManager)myContext.getSystemService(Context.AUDIO_SERVICE);
int max = mAudioManager.getStreamMaxVolume(streamType);
if (vol>max){
vol=max;
}
mAudioManager.setStreamVolume(streamType,vol, 0);
}
}
修改
以下代码是否正确?我按你的想法修改了原始代码。
我无法理解为什么代码需要添加HashMap,我认为sTts.get().setOnUtteranceProgressListener
和sTts.get().setOnUtteranceCompletedListener
不需要HashMap,对吗?
HashMap ttsParameters = new HashMap(); ttsParameters.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID “的StringID”);
包bll;
公共课SpeechTxt {
private static SoftReference sTts;
public static void SpeakOut(final Context context, final String s) {
final Context appContext = context.getApplicationContext();
if (sTts == null) {
sTts = new SoftReference<TextToSpeech>(new TextToSpeech(appContext,
new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
speak(appContext, s);
} else {
}
}
}));
} else {
speak(appContext, s);
}
}
private static void speak(Context context, String s) {
if (sTts != null) {
switch (sTts.get().setLanguage(Locale.getDefault())) {
case TextToSpeech.LANG_COUNTRY_AVAILABLE:
case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
case TextToSpeech.LANG_AVAILABLE: {
sTts.get().setPitch((float) 0.6);
sTts.get().setSpeechRate((float) 0.8);
final int currentRing=PublicParFun.GetCurrentVol(context, AudioManager.STREAM_RING);
final int currentPlay=PublicParFun.GetCurrentVol(context, AudioManager.STREAM_MUSIC);
PublicParFun.SetRingVol(context, 0);
PublicParFun.SetPlayVol(context,1000000);
final Context myContext=context;
HashMap<String, String> ttsParameters = new HashMap<String, String>();
ttsParameters.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"stringId");
if (android.os.Build.VERSION.SDK_INT >=15){
sTts.get().setOnUtteranceProgressListener(new UtteranceProgressListener()
{
@Override
public void onDone(String utteranceId)
{
PublicParFun.SetRingVol(myContext, currentRing);
PublicParFun.SetPlayVol(myContext,currentPlay);
}
@Override
public void onError(String utteranceId)
{
//also, set the volume back
}
@Override
public void onStart(String utteranceId)
{
// set the volume to max
}
});
}else{
sTts.get().setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String utteranceId) {
PublicParFun.SetRingVol(myContext, currentRing);
PublicParFun.SetPlayVol(myContext,currentPlay);
}
});
}
sTts.get().speak(s, TextToSpeech.QUEUE_ADD, ttsParameters);
break;
}
case TextToSpeech.LANG_MISSING_DATA: {
break;
}
case TextToSpeech.LANG_NOT_SUPPORTED: // not much to do here
}
}
}
}
再次编辑
我测试了很多次,当sTts.get()。speak(s,TextToSpeech.QUEUE_ADD,ttsParameters)说一个短字符串时,sTts.get()。setOnUtteranceCompletedListener(新的OnUtteranceCompletedListener()被正确调用。
但是如果sTts.get()。speak(s,TextToSpeech.QUEUE_ADD,ttsParameters)说一个长字符串(大约15秒),似乎没有调用sTts.get()。setOnUtteranceCompletedListener(new OnUtteranceCompletedListener()为什么?
sTts.get().setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String utteranceId) {
PublicParFun.SetRingVol(myContext, currentRing);
PublicParFun.SetPlayVol(myContext,currentPlay);
}
});
答案 0 :(得分:5)
问题可能是,您在启动TTS之后直接设置了currentRingVolume。代码不会等到演讲结束。要将音量设置回当前音量,请在演讲结束后使用UtteranceProgressListener(或onUtteranceCompletetListener&lt; API 15.这取决于您正在开发的API):
//first set the HashMap to Your tts
HashMap<String, String> ttsParameters = new HashMap<String, String>();
ttsParameters.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"stringId");
tts.speak("Say Hello",TextToSpeech.QUEUE_FLUSH, ttsParameters );
设置onUtteranceProgressListener:
int result = tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
{
@Override
public void onDone(String utteranceId)
{
//here set the volume back
}
@Override
public void onError(String utteranceId)
{
//also, set the volume back
}
@Override
public void onStart(String utteranceId)
{
// set the volume to max
}
});
和API&lt; 15:
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String utteranceId) {
//set volume back
}
});
要找出安装的版本:
if (android.os.Build.VERSION.SDK_INT >=8){
}