TTS ONUTERANCE已完成,无法在Android中工作
我正在开发android中与dialogflow集成的语音识别器模块。我几乎完成了集成,它工作得很好,但面临一个问题。问题在于TTS在完成语音麦克风之前说出响应,它也会捕获响应,而不仅仅是用户的声音 所以我想知道我怎样才能知道TTS已经完成了回答?我尝试过使用onutternancecompleted()方法来解决Google问题,也尝试过setonutternanceprogresslistener()方法,但似乎不起作用。我想在asynctask中实现这些方法,以便可以在后台完成。我该怎么做 以下是我尝试过的代码:TTS ONUTERANCE已完成,无法在Android中工作,android,android-asynctask,dialogflow-es,text-to-speech,onutterancecompleted,Android,Android Asynctask,Dialogflow Es,Text To Speech,Onutterancecompleted,我正在开发android中与dialogflow集成的语音识别器模块。我几乎完成了集成,它工作得很好,但面临一个问题。问题在于TTS在完成语音麦克风之前说出响应,它也会捕获响应,而不仅仅是用户的声音 所以我想知道我怎样才能知道TTS已经完成了回答?我尝试过使用onutternancecompleted()方法来解决Google问题,也尝试过setonutternanceprogresslistener()方法,但似乎不起作用。我想在asynctask中实现这些方法,以便可以在后台完成。我该怎么做
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import ai.api.PartialResultsListener;
import ai.api.android.AIConfiguration;
import ai.api.android.GsonFactory;
import ai.api.model.AIError;
import ai.api.model.AIResponse;
import ai.api.ui.AIDialog;
import android.os.AsyncTask;
import com.google.gson.Gson;
public class VoiceActivity extends AppCompatActivity implements View.OnClickListener, TextToSpeech.OnInitListener, RecognitionListener {
private AIDialog.AIDialogListener resultsListener;
private static final int REQUEST_AUDIO_PERMISSIONS_ID = 33;
private Gson gson = GsonFactory.getGson();
private ListView wordList;
TextView txtmain;
private static final int VR_REQUEST = 999;
//Log tag for output information
private final String LOG_TAG = "SpeechRepeatActivity";//***enter your own tag here***
//variable for checking TTS engine data on user device
private int MY_DATA_CHECK_CODE = 0;
//Text To Speech instance
private TextToSpeech tts;
AIButton aiButton;
EditText time;
TextView matchcall;
// private SpeechRecognizer speech = null;
private Intent recognizerIntent;
TextView tvOutput ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_voice);
aiButton = (AIButton) findViewById(R.id.speech_btn);
txtmain =findViewById(R.id.txtmain);
wordList = findViewById(R.id.word_list);
tvOutput = findViewById(R.id.tvOutput);
time = (EditText) findViewById(R.id.in_time);
matchcall = (TextView) findViewById(R.id.matchcall);
final AsyncTaskRunner runner = new AsyncTaskRunner();
initService();
PackageManager packManager = getPackageManager();
List<ResolveInfo> intActivities = packManager.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
if (intActivities.size() != 0) {
//speech recognition is supported - detect user button clicks
aiButton.setOnClickListener(this);
//prepare the TTS to repeat chosen words
Intent checkTTSIntent = new Intent();
//check TTS data
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
//start the checking Intent - will retrieve result in onActivityResult
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
} else {
//speech recognition not supported, disable button and output message
aiButton.setEnabled(false);
Toast.makeText(this, "Oops - Speech recognition not supported!", Toast.LENGTH_LONG).show();
}
}
private void setAIButtonCallback(final AIButton aiButton) {
aiButton.setResultsListener(new AIButton.AIButtonListener() {
@Override
public void onResult(final AIResponse result) {
if (resultsListener != null) {
resultsListener.onResult(result);
Log.e(LOG_TAG,"onResult=="+result.getResult().getResolvedQuery());
final String speech = result.getResult().getFulfillment().getSpeech();
tvOutput.setText(speech);
}
}
@Override
public void onError(final AIError error) {
if (resultsListener != null) {
resultsListener.onError(error);
Log.e(LOG_TAG,"onError=="+error);
}
}
@Override
public void onCancelled() {
if (resultsListener != null) {
resultsListener.onCancelled();
Log.e(LOG_TAG,"onCancelled==");
}
}
});
aiButton.setPartialResultsListener(new PartialResultsListener() {
@Override
public void onPartialResults(final List<String> partialResults) {
final String result = partialResults.get(0);
if (!TextUtils.isEmpty(result)) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
txtmain.setText(result);
}
});
}
}
});
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.speech_btn) {
//listen for results
listenToSpeech();
}
}
@Override
public void onInit(int status) {
//if successful, set locale
if (status == TextToSpeech.SUCCESS)
tts.setLanguage(Locale.UK);//***choose your own locale here***
}
private void listenToSpeech() {
SpeechRecognizer speech = SpeechRecognizer.createSpeechRecognizer(this);
speech.setRecognitionListener(this);
recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,"en");
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,this.getPackageName());
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,this.getPackageName());
recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
//start listening
speech.startListening(recognizerIntent);
}
@Override
public void onResults(Bundle results) {
Log.i(LOG_TAG, "onResults");
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
/* wordList.setAdapter(new ArrayAdapter<String>(this, R.layout.word, matches));
new Handler().post(new Runnable() {
@Override
public void run() {
wordList.performItemClick(
wordList.getChildAt(0),
0,
wordList.getAdapter().getItemId(0));
wordList.getChildAt(0).setBackgroundColor(0xFFD3D3D3);
}
});*/
String wordChosen = matches.get(0);
tvOutput.setText(wordChosen);
try {
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute(wordChosen);
// aiButton.textRequest(text);
//runner.doInBackground(text);
} catch (Exception e) {
e.printStackTrace();
}
}
private class AsyncTaskRunner extends AsyncTask<String, AIResponse, AIResponse> {
private AIResponse resp;
ProgressDialog progressDialog;
@Override
protected AIResponse doInBackground(String... params) {
Log.e(LOG_TAG,"doInBackground=="+params[0]);
try {
resp = aiButton.textRequest(String.valueOf(params[0]));
}
catch (Exception e) {
e.printStackTrace();
}
return resp;
}
protected void onPostExecute(AIResponse result) {
Log.e(LOG_TAG,"onPostExecute== result=="+result.getResult().getFulfillment().getSpeech());
// execution of result of Long time consuming operation
findViewById(R.id.progBar).setVisibility(View.GONE);
txtmain.setText(result.getResult().getFulfillment().getSpeech());
String speech = result.getResult().getFulfillment().getSpeech();
tts.speak( speech, TextToSpeech.QUEUE_FLUSH, null);
Toast.makeText(VoiceActivity.this, speech, Toast.LENGTH_SHORT).show();
listenToSpeech();
}
@Override
protected void onPreExecute() {
Log.e(LOG_TAG,"onPreExecute==");
findViewById(R.id.progBar).setVisibility(View.VISIBLE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//check speech recognition result
if (requestCode == VR_REQUEST && resultCode == RESULT_OK)
{
//store the returned word list as an ArrayList
ArrayList<String> suggestedWords = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
//set the retrieved list to display in the ListView using an ArrayAdapter
wordList.setAdapter(new ArrayAdapter<String>(this, R.layout.word, suggestedWords));
/*new Handler().post(new Runnable() {
@Override
public void run() {
wordList.performItemClick(
wordList.getChildAt(0),
0,
wordList.getAdapter().getItemId(0));
wordList.getChildAt(0).setBackgroundColor(0xFFD3D3D3);
}
});*/
tvOutput.setText(suggestedWords.get(0));
}
if (requestCode == MY_DATA_CHECK_CODE)
{
//we have the data - create a TTS instance
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS)
tts = new TextToSpeech(this, this);
//data not installed, prompt the user to install it
else
{
//intent will take user to TTS download page in Google Play
Intent installTTSIntent = new Intent();
installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
//call superclass method
super.onActivityResult(requestCode, resultCode, data);
}
private void initService() {
final AIConfiguration config = new AIConfiguration("a73d5e88477e4926ae84af46f24e0aaa",
AIConfiguration.SupportedLanguages.English,
AIConfiguration.RecognitionEngine.Google);
aiButton.initialize(config);
setAIButtonCallback(aiButton);
Log.i(LOG_TAG, "initService:::::: ");
}
@Override
protected void onPause() {
super.onPause();
// speech.stopListening();
// use this method to disconnect from speech recognition service
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
5000
);
// Not destroying the SpeechRecognition object in onPause method would block other apps from using SpeechRecognition service
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStop() {
Log.i(LOG_TAG, "stop");
super.onStop();
/* if (speech != null) {
speech.destroy();*/
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//}
@Override
protected void onStart() {
super.onStart();
checkAudioRecordPermission();
}
protected void checkAudioRecordPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.RECORD_AUDIO)) {
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
REQUEST_AUDIO_PERMISSIONS_ID);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_AUDIO_PERMISSIONS_ID: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
}
return;
}
}
}
@Override
public void onReadyForSpeech(Bundle bundle) {
}
@Override
public void onBeginningOfSpeech() {
}
@Override
public void onRmsChanged(float v) {
}
@Override
public void onBufferReceived(byte[] bytes) {
}
@Override
public void onEndOfSpeech() {
//speech.stopListening();
}
@Override
public void onError(int errorcode) {
String errorMessage = getErrorText(errorcode);
Log.i(LOG_TAG, "FAILED " + errorMessage);
// speech.stopListening();
// listenToSpeech();
}
public String getErrorText(int errorCode) {
String message;
switch (errorCode) {
case SpeechRecognizer.ERROR_AUDIO:
message = "Audio recording error";
break;
case SpeechRecognizer.ERROR_CLIENT:
message = "Client side error";
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
message = "Insufficient permissions";
break;
case SpeechRecognizer.ERROR_NETWORK:
message = "Network error";
break;
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
message = "Network timeout";
break;
case SpeechRecognizer.ERROR_NO_MATCH:
message = "No match";
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
message = "RecognitionService busy";
break;
case SpeechRecognizer.ERROR_SERVER:
message = "error from server";
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
message = "No speech input";
//speech.stopListening();
break;
default:
message = "Didn't understand, please try again.";
break;
}
return message;
}
@Override
public void onPartialResults(Bundle bundle) {
}
@Override
public void onEvent(int i, Bundle bundle) {
}
}
导入android.Manifest;
导入android.app.ProgressDialog;
导入android.content.Intent;
导入android.content.pm.PackageManager;
导入android.content.pm.ResolveInfo;
导入android.os.Bundle;
导入android.os.Handler;
导入android.os.Looper;
导入android.speech.RecognitionListener;
导入android.speech.RecognizerIntent;
导入android.SpeechRecognizer;
导入android.speech.tts.TextToSpeech;
导入android.support.annotation.NonNull;
导入android.support.v4.app.ActivityCompat;
导入android.support.v4.content.ContextCompat;
导入android.support.v7.app.AppActivity;
导入android.text.TextUtils;
导入android.util.Log;
导入android.view.view;
导入android.widget.ArrayAdapter;
导入android.widget.EditText;
导入android.widget.ListView;
导入android.widget.TextView;
导入android.widget.Toast;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Locale;
导入ai.api.PartialResultsListener;
导入ai.api.android.AIConfiguration;
导入ai.api.android.gson工厂;
导入ai.api.model.AIError;
导入ai.api.model.AIResponse;
导入ai.api.ui.AIDialog;
导入android.os.AsyncTask;
导入com.google.gson.gson;
公共类VoiceActivity扩展AppCompativeActivity实现View.OnClickListener、TextToSpeech.OnInitListener、RecognitionListener{
私有AIDialog.AIDialogListener结果监听器;
私有静态最终整数请求\u音频\u权限\u ID=33;
私有Gson Gson=GsonFactory.getGson();
私有列表视图单词列表;
TextView-txtmain;
专用静态最终int VR_请求=999;
//输出信息的日志标记
私有最终字符串日志\u TAG=“SpeechRepeatActivity”//***在此处输入您自己的标记***
//用于检查用户设备上的TTS引擎数据的变量
私有int MY_DATA_CHECK_CODE=0;
//文本到语音实例
私密文本语音tts;
AIButton AIButton;
编辑文本时间;
文本视图匹配调用;
//专用语音识别器语音=null;
私人意图识别人意图;
文本视图输出;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u voice);
aiButton=(aiButton)findviewbyd(R.id.speech\u btn);
txtmain=findviewbyd(R.id.txtmain);
wordList=findviewbyd(R.id.word\u列表);
tvOutput=findViewById(R.id.tvOutput);
时间=(EditText)findViewById(R.id.in_time);
matchcall=(TextView)findViewById(R.id.matchcall);
最终AsyncTaskRunner=新的AsyncTaskRunner();
initService();
PackageManager packManager=getPackageManager();
List intActivities=packManager.queryintactivities(新意图(RecognizerIntent.ACTION\u RECOGNIZE\u SPEECH),0);
if(intActivities.size()!=0){
//支持语音识别-检测用户按钮点击
aiButton.setOnClickListener(此);
//准备TTS以重复所选单词
Intent checkttsinent=新Intent();
//检查TTS数据
checkttsinent.setAction(TextToSpeech.Engine.ACTION\u CHECK\u TTS\u数据);
//启动检查意图-将在onActivityResult中检索结果
startActivityForResult(检查输入、我的数据检查代码);
}否则{
//不支持语音识别,禁用按钮并输出消息
aiButton.setEnabled(假);
Toast.makeText(这是“Oops-语音识别不受支持!”,Toast.LENGTH_LONG.show();
}
}
专用无效设置AIButton回调(最终AIButton AIButton){
aiButton.setResultsListener(新的aiButton.AIButtonListener(){
@凌驾
公开无效结果(最终空中响应结果){
if(resultsListener!=null){
resultsListener.onResult(结果);
Log.e(Log_标记,“onResult=”+result.getResult().getResolvedQuery());
最后一个字符串speech=result.getResult().getFulfillment().getSpeech();
tvOutput.setText(语音);
}
}
@凌驾
公共无效onError(最终AIError错误){
if(resultsListener!=null){
resultsListener.onError(错误);
Log.e(Log_标签,“onError==”+错误);
}
}
@凌驾
已取消的公共无效(){
if(resultsListener!=null){
resultsListener.onCancelled();
Log.e(Log_标记,“onCancelled==”);
}
}
});
setPartialResultsListener(新的PartialResultsListener(){
@凌驾
public void on partialResults(最终列表partialResults){
最终字符串结果=partialResults.get(0);
如果(!TextUtils.isEmpty(结果)){
新的处理程序(Looper.getMainLooper()).post(新的Runnable()){
@凌驾