我正在为 android-23 使用 PocketSphinx。我想为我的一个应用程序编写一个离线助手。我已成功使用识别器.addKeyphraseSearch 来初始化助手。例如。在这种情况下,我说“你好”来初始化它。
这是我的全部代码
public class Farmax_2 extends Activity implements
RecognitionListener {
/* Named searches allow to quickly reconfigure the decoder */
private static final String KWS_SEARCH = "wakeup";
private static final String ahead = "about";
private static final String PHONE_SEARCH = "ahead";
private static final String MENU_SEARCH = "menu";
TextToSpeech t1;
Button btn;
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "hello";
/* Used to handle permission request */
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_farmax_2);
// Check if user has given permission to record audio
int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
return;
}
btn=(Button)findViewById(R.id.buttonme);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent inte = new Intent(Farmax_2.this, MainMenu.class);
startActivity(inte);
}
});
t1 = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.UK);
}
}
});
runRecognizerSetup();
}
public void omku(View view) { Intent in=new Intent(this,abtus.class);
startActivity(in);}
private void runRecognizerSetup() {
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new AsyncTask<Void, Void, Exception>() {
@Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(Farmax_2.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
@Override
protected void onPostExecute(Exception result) {
if (result != null) {
} else {
switchSearch(KWS_SEARCH);
}
}
}.execute();
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
runRecognizerSetup();
} else {
finish();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (recognizer != null) {
recognizer.cancel();
recognizer.shutdown();
}
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
@Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
switch (text) {
case KEYPHRASE: {
omkar();
break;
}
case ahead: {
Intent in = new Intent(this, abtus.class);
startActivity(in);
break;
// t1.speak("taking you to privacy policy of farmax.", TextToSpeech.QUEUE_FLUSH, null);
}
case PHONE_SEARCH: {
Intent in = new Intent(this, MainMenu.class);
startActivity(in);
// t1.speak("Main Menu.", TextToSpeech.QUEUE_FLUSH, null);
break;
}
}
}
private void omkar() {
t1.speak("Yes sir.", TextToSpeech.QUEUE_FLUSH, null);
switchSearch(MENU_SEARCH);
}
/**
* This callback is called when we stop the recognizer.
*/
@Override
public void onResult(Hypothesis hypothesis) {
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onBeginningOfSpeech() {
}
/**
* We stop recognizer here to get a final result
*/
@Override
public void onEndOfSpeech() {
}
private void switchSearch(String searchName) {
recognizer.stop();
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(KWS_SEARCH))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = SpeechRecognizerSetup.defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
.setRawLogDir(assetsDir) // To disable logging of raw audio comment out this call (takes a lot of space on the device)
.getRecognizer();
recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, "hello");
// Create grammar-based search for selection between demos
File menuGrammar = new File(assetsDir, "firstscn.gram");
recognizer.addGrammarSearch(MENU_SEARCH, menuGrammar);
// Create grammar-based search for digit recognition
}
@Override
public void onError(Exception error) {
}
@Override
public void onTimeout() {
switchSearch(KWS_SEARCH);
}
}
当我打招呼时,它会通过 tts 回复“是的先生”来正确响应。但在那之后它应该切换菜单并等待进一步的命令。在这种情况下,有两个。
@Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
switch (text) {
case KEYPHRASE: {
omkar();
break;
}
case ahead: {
Intent in = new Intent(this, abtus.class);
startActivity(in);
break;
// t1.speak("taking you to privacy policy of farmax.", TextToSpeech.QUEUE_FLUSH, null);
}
case PHONE_SEARCH: {
Intent in = new Intent(this, MainMenu.class);
startActivity(in);
// t1.speak("Main Menu.", TextToSpeech.QUEUE_FLUSH, null);
break;
}
}
}
但问题是它在切换菜单后不等待我的命令。
有时吐司会弹出“关于”或有时会出现“提前”,即使我不说它们。在那之后,该应用程序严重冻结,除了关闭它,我别无选择。
if 也尝试过除了 switch 和 case 之外的 if else 语句。但他们似乎没有多大帮助。我也尝试在 onResult 而不是 onPartialResult 中使用上述代码,但这也无济于事。
使用 sphinx 工具,我创建了自己的字典和语法文件。这是本例的语法文件内容。
#JSGF V1.0;
grammar firstscn;
public <item> = about | ahead;
我哪里错了?请帮我。