我有一个功能齐全的自定义Android键盘,我必须添加语音识别。以下是我实施的相关部分
public class CustomInputMethodService
extends InputMethodService
implements <random stuff> {
private SpeechRecognizer mSpeechRecognizer;
private RecognitionListener mSpeechlistener;
public void onCreate() {
super.onCreate();
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechlistener = new CustomRecognitionListener();
mSpeechRecognizer.setRecognitionListener(mSpeechlistener);
}
@Override
public void onPress(int primaryCode) {
if (primaryCode == KeyCodes.VOICE_INPUT) {
mSpeechRecognizer.startListening(getSpeechIntent());
}else if(..){
...
}
}
private Intent getSpeechIntent() {
Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
speechIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, false);
return speechIntent;
}
}
CustomRecognitionListener的相关方法很简单:
@Override
public void onResults(Bundle results) {
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Log.d(TAG, "onResults: ----> " + matches.get(0));
if(matches != null && matches.size() > 0) {
writeText(matches.get(0));
}
}
此代码工作得很好。这里的转折是我想要一个类似的行为,当uset点击麦克风键时谷歌键盘上发生的事情:
理想情况下,这可以通过以下方式实现:
Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
try {
startActivityForResult(voiceIntent, Constants.RESULT_SPEECH);
} catch (ActivityNotFoundException ex) {
DebugLog.e(TAG, "Not found excpetion onKeyDown: " + ex);
}
但是,由于密钥监听器已启用且InputMethodService无法调用startActivityForResult。 实现这一目标的理想方法是什么?我应该只是在没有布局的情况下启动新活动并回调inputMethodService吗?看起来很乱
答案 0 :(得分:2)
您的屏幕截图显示了“Google语音输入”,这是一个独立的IME,当按下麦克风按钮时,Google键盘会调用该IME。因此,您的IME应该这样做:用提供语音输入的IME替换自己,并希望在完成语音输入后,您的IME会有反向链接。
最简单的实现方式是Switching among IME Subtypes,但您可能希望获得更多控制权,例如启动具有特定输入参数的特定IME等。我不确定实现这种额外控制的最佳/标准方法是什么。
有关语音输入IME的示例,您可以查看(我的应用)Kõnele。
答案 1 :(得分:1)
解决方案的简单实施:
// on mic tap we call
public void startVoiceListening() {
InputMethodManager imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
String voiceExists = voiceExists(imeManager);
if (voiceExists != null) {
final IBinder token = getWindow().getWindow().getAttributes().token;
imeManager.setInputMethod(token,voiceExists);
}
}
private String voiceExists(InputMethodManager imeManager) {
List<InputMethodInfo> list = imeManager.getInputMethodList();
for (InputMethodInfo el : list) {
// do something to check whatever IME we want.
// in this case "com.google.android.googlequicksearchbox"
}
return null;
}
一旦我们不再想要使用当前的IME,只需关闭它,它就会回到之前的那个