2

音声認識を追加する必要がある、完全に機能するカスタム 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 がマイク キーをタップしたときに Google キーボードで発生するのと同様の動作が必要なことです。

ここに画像の説明を入力

これは、理想的には次のような方法で達成されます。

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 へのコールバックを設定する必要がありますか? 乱雑に見える

4

2 に答える 2

2

スクリーンショットは、「Google 音声入力」を示しています。これは、マイク ボタンが押されたときに Google キーボードによって呼び出される独立した IME です。したがって、IME も同じことを行う必要があります。音声入力を提供する IME に置き換え、音声入力が完了したら、IME へのバックリンクがあることを期待します。

最も単純な実装はSwitching between IME Subtypesですが、特定の IME を特定の入力パラメーターで開始するなど、より詳細な制御が必要になる場合があります。

音声入力 IME の例については、(私のアプリ) Kõneleを調べることができます。

于 2017-01-05T11:22:53.287 に答える
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 を使用する必要がなくなったら、閉じるだけで以前の IME に戻ります

于 2017-01-05T11:29:25.397 に答える