/* * Copyright (C) 2014 Fastboot Mobile, LLC. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses>. */ package com.fastbootmobile.encore.voice; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.speech.RecognitionListener; import android.speech.RecognizerIntent; import android.speech.SpeechRecognizer; import android.util.Log; import com.fastbootmobile.encore.app.BuildConfig; import java.util.ArrayList; import java.util.List; /** * Helper class for voice commands */ public class VoiceRecognizer implements RecognitionListener { private static final String TAG = "VoiceRecognizer"; private static final boolean DEBUG = BuildConfig.DEBUG; private SpeechRecognizer mSpeechRecognizer; private Intent mSpeechRecognizerIntent; private Listener mListener; public VoiceRecognizer(Context context) { mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context); mSpeechRecognizer.setRecognitionListener(this); mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName()); mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10); mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "What can I do?"); } public void setListener(Listener listener) { mListener = listener; } public void startListening() { mSpeechRecognizer.startListening(mSpeechRecognizerIntent); } /** * Called when the endpointer is ready for the user to start speaking. * * @param params Reserved for future use */ @Override public void onReadyForSpeech(Bundle params) { if (DEBUG) Log.d(TAG, "Ready for speech"); if (mListener != null) { mListener.onReadyForSpeech(); } } /** * The user has started to speak. */ @Override public void onBeginningOfSpeech() { if (DEBUG) Log.d(TAG, "Began speaking"); if (mListener != null) { mListener.onBeginningOfSpeech(); } } /** * The sound level in the audio stream has changed. There is no guarantee that this method will * be called. * * @param rmsdB the new RMS dB value */ @Override public void onRmsChanged(float rmsdB) { if (mListener != null) { mListener.onRmsChanged(rmsdB); } } /** * More sound has been received. The purpose of this function is to allow giving feedback to * the user regarding the captured audio. There is no guarantee that this method will be called. * * @param buffer a buffer containing a sequence of big-endian 16-bit integers representing a * single channel audio stream. The sample rate is implementation dependent. */ @Override public void onBufferReceived(byte[] buffer) { } /** * Called after the user stops speaking. */ @Override public void onEndOfSpeech() { if (DEBUG) Log.d(TAG, "End of speech"); if (mListener != null) { mListener.onEndOfSpeech(); } } /** * A network or recognition error occurred. * * @param error code defined in {@link android.speech.SpeechRecognizer} */ @Override public void onError(int error) { if (DEBUG) { String errorMsg; switch (error) { case SpeechRecognizer.ERROR_AUDIO: errorMsg = "Audio recording error"; break; case SpeechRecognizer.ERROR_CLIENT: errorMsg = "No voice recnogition service available"; break; case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: errorMsg = "Insufficient permissions"; break; case SpeechRecognizer.ERROR_NETWORK: errorMsg = "Network error"; break; case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: errorMsg = "Network operation timed out"; break; case SpeechRecognizer.ERROR_NO_MATCH: errorMsg = "No matches"; break; case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: errorMsg = "Recognition service is busy"; break; case SpeechRecognizer.ERROR_SERVER: errorMsg = "Server error"; break; case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: errorMsg = "No speech input"; break; default: errorMsg = "Unknown error"; break; } Log.d(TAG, "Error " + error + ": " + errorMsg); } if (mListener != null) { mListener.onError(error); } } /** * Called when recognition results are ready. * * @param results the recognition results. To retrieve the results in ArrayList<String> format * use getStringArrayList(String) with RESULTS_RECOGNITION as a parameter. A * float array of confidence values might also be given in CONFIDENCE_SCORES. */ @Override public void onResults(Bundle results) { if (DEBUG) Log.d(TAG, "Results received"); ArrayList<String> data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if (mListener != null) { mListener.onResults(data); } } /** * Called when partial recognition results are available. The callback might be called at any * time between onBeginningOfSpeech() and onResults(Bundle) when partial results are ready. * This method may be called zero, one or multiple times for each call to * {@link #startListening()}, depending on the speech recognition service implementation. * To request partial results, use EXTRA_PARTIAL_RESULTS * * @param partialResults the returned results. To retrieve the results in ArrayList<String> * format use getStringArrayList(String) with RESULTS_RECOGNITION as * a parameter */ @Override public void onPartialResults(Bundle partialResults) { if (DEBUG) Log.d(TAG, "Partial results received"); ArrayList<String> data = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if (mListener != null) { mListener.onPartialResults(data); } } @Override public void onEvent(int eventType, Bundle params) { if (DEBUG) Log.d(TAG, "Event " + eventType); } public interface Listener { public void onReadyForSpeech(); public void onBeginningOfSpeech(); public void onEndOfSpeech(); public void onRmsChanged(float rmsdB); public void onError(int error); public void onResults(List<String> results); public void onPartialResults(List<String> results); } }