[Android] Nhận dạng giọng nói - Speech Recognition
Tìm hiểu và cài đặt tính năng Nhận dạng giọng nói - Speech Recognition trong Android
Giới thiệu
Trong những bộ phim khoa học viễn tưởng, chúng ta rất thường hay thấy cảnh con người tương tác với các thiết bị điện tử bằng giọng nói. Giấc mơ này đã có từ khá lâu và bây giờ nó đang dần trở thành hiện thực. Những chiếc smartphone, tablet giờ đây đều có tính năng điều khiển bằng giọng nói, một số sản phẩm thậm chí còn trả lời lại người dùng như thể hai người đang nói chuyện với nhau. Sự ra đời của công nghệ này đã trở thành một xu hướng mới mẻ trong thị trường ứng dụng di động.
Các bạn có thể thấy ứng dụng của nó ở khắp nơi, dễ nhìn thấy nhất là từ các ông lớn Google (Google Voice), Apple (Siri), Microsoft (Cortana), Amazon (Alexa)... Tất nhiên, hiện nay công nghệ giọng nói vẫn chỉ mới ở giai đoạn đầu chứ chưa thể nào thay thế hoàn toàn bàn phím ảo/vật lý hoặc các nút trên màn hình. Tuy nhiên, chúng ta đang dần tiến đến một kỉ nguyên hiện đại hơn, các ứng dụng giọng nói cũng dần dần được hoàn thiện. Nó đang dần chuyển thành xu thế mới của các ứng dụng ngày nay.
Xây dựng ứng dụng
Đầu tiên chúng ta cần có:
- class SpeechRecognitionListener dùng để lắng nghe các sự kiện được implements từ class RecognitionListener
- class SpeechRecognizerManager dùng để quản lý cũng như xử lý các hành động
- interface onResultsReady như một callback để trả dữ liệu về cho Activity
Bắt đầu với onResultsReady
public interface onResultsReady
{
// Trả về dữ liệu khi hoàn thành nhận dạng hoặc gặp lỗi
public void onResults(ArrayList<String> results);
// Trả về dữ liệu mỗi khi chúng ta nói
public void onStreamingResult(ArrayList<String> partialResults);
}
Interface này được sử dụng để chúng ta trả dữ liệu về cho activity. Nó trả về 2 kiểu kết quả
- Từng kết quả mà nó nhận điện được trong quá trình chúng ta nói (onStreamingResult)
- Kết quả cuối cùng của cả câu (đoạn) mà chúng ta đã nói (onResults)
SpeechRecognitionListener
protected class SpeechRecognitionListener implements RecognitionListener
{
@Override
public void onBeginningOfSpeech() {}
@Override
public void onBufferReceived(byte[] buffer) { }
@Override
public void onEndOfSpeech() {}
@Override
public synchronized void onError(int error) { }
@Override
public void onEvent(int eventType, Bundle params) {}
@Override
public void onPartialResults(Bundle partialResults) { }
@Override
public void onReadyForSpeech(Bundle params) {}
@Override
public void onResults(Bundle results) { }
@Override
public void onRmsChanged(float rmsdB) {}
}
Class SpeechRecognitionListener chúng ta implements từ RecognitionListener, nó cho phép chúng ta tham gia vào quá trình xử lý dữ liệu của SpeechRecognizer. Có 3 phương thức chúng ta cần phải viết lại, bao gồm onError (khi gặp lỗi), onPartialResults (khi nhận kết quả UNSTABLE), onResults (khi nhận kết quả cuối cùng).
Phương thức onError cho phép chúng ta xử lý các lỗi sau:
- SpeechRecognizer.ERROR_AUDIO: Audio recording error.
- SpeechRecognizer.ERROR_CLIENT: Other client side errors.
- SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: Insufficient permissions
- SpeechRecognizer.ERROR_NETWORK: Other network related errors.
- SpeechRecognizer.ERROR_NETWORK_TIMEOUT: Network operation timed out.
- SpeechRecognizer.ERROR_NO_MATCH: No recognition result matched.
- SpeechRecognizer.ERROR_RECOGNIZER_BUSY: RecognitionService busy.
- SpeechRecognizer.ERROR_SERVER: Server sends error status.
- SpeechRecognizer.ERROR_SPEECH_TIMEOUT: No speech input
// private onResultsReady mListener;
// mListener là 1 biến private nằm trong SpeechRecognizerManager
@Override
public synchronized void onError(int error) {
if (error == SpeechRecognizer.ERROR_NETWORK) {
ArrayList<String> errorList = new ArrayList<String>(1);
errorList.add("STOPPED LISTENING");
if (mListener != null) {
mListener.onResults(errorList);
Toast.makeText(mContext, "NETWORK ERROR", Toast.LENGTH_SHORT).show();
}
}
// Các lỗi khác các bạn check tương tự
}
@Override
public void onPartialResults(Bundle partialResults) {
if (partialResults != null && mListener != null) {
ArrayList<String> texts = partialResults.getStringArrayList("android.speech.extra.UNSTABLE_TEXT");
mListener.onStreamingResult(texts);
}
}
@Override
public void onResults(Bundle results) {
if (results != null && mListener != null) {
ArrayList<String> ahihi = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
mListener.onResults(ahihi);
}
}
SpeechRecognizerManager
Các bạn có thể check các ngôn ngữ mà google hỗ trợ ở đây: https://cloud.google.com/speech/docs/languages Đoạn code ở dưới mình đặt ngôn ngữ hỗ trợ là tiếng Nhật và thời gian dừng tối đa là 2s.
public class SpeechRecognizerManager {
private final static String TAG = "SpeechRecognizerManager";
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
private Context mContext;
protected boolean mIsListening;
protected String language = "ja"; // các bạn có thể đổi sang ngôn ngữ khác theo như ý muốn
protected long timeout = 2000l; // 2000 ms
private onResultsReady mListener;
public SpeechRecognizerManager(Context context, onResultsReady listener)
{
try {
mListener = listener;
} catch(ClassCastException e) {
Log.e(TAG, e.toString());
}
mContext = context;
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);
mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
// Create new intent
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, language);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, language);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE, language);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); // For streaming result
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, timeout);
// Start listening
startListening();
}
private void startListening()
{
if (!mIsListening) {
mIsListening = true;
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
}
public void stop() {
if (mIsListening && mSpeechRecognizer != null) {
mSpeechRecognizer.stopListening();
mSpeechRecognizer.cancel();
mSpeechRecognizer.destroy();
mSpeechRecognizer = null;
}
mIsListening = false;
}
public void destroy()
{
mIsListening = false;
if (mSpeechRecognizer != null) {
mSpeechRecognizer.stopListening();
mSpeechRecognizer.cancel();
mSpeechRecognizer.destroy();
mSpeechRecognizer = null;
}
}
public boolean ismIsListening() {
return mIsListening;
}
}
Giải thích 1 chút về đoạn code trên:
- Từ Activity chúng ta khởi tạo một SpeechRecognizerManager với 2 tham số Context và onResultsReady
- Trong constructor của SpeechRecognizerManager, chúng ta tạo mới một SpeechRecognizer sử dụng SpeechRecognitionListener ở trên. Tiếp theo tạo một Intent và startListening. Thế là xong @@
Code: các bạn có thể check full code ở SpeechRecognizerManager.java
Cảm ơn các bạn đã đọc bài viết. Chào thân ái và quyết thắng!
Bài viết gốc: https://viblo.asia/p/android-speech-recognition-1Je5E8bAlnL
Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!