Android - Speech Recognition
Bài đăng này đã không được cập nhật trong 6 năm
Tiếp nối bài viết về Web Speech Recognition, bài viết này của mình sẽ viết về Speech Recognition
trên Android.
Trên viblo cũng có mấy bài viết hướng dẫn sử dụng Speech Recognition
trên Android, tuy nhiên các ví dụ trong đó đều yêu cầu sử dụng popup
để bắt đầu nhận dạng giọng nói và chỉ cho phép chúng ta xem kết quả sau khi hoàn thành câu nói. Trong bài viết này mình sẽ hướng dẫn các bạn thực hiện nhận diện giọng nói
mà không phải bật popup
và có thể xem các partial results
.
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
Chúng ta bắt đầu xây dựng ứng dụng
nhận dạng giọng nói trên Android.
Đầu tiên chúng ta cần có:
- class
SpeechRecognitionListener
dùng đểlắng nghe
các sự kiện đượcimplements
từ classRecognitionListener
- class
SpeechRecognizerManager
dùng để quản lý cũng như xử lý cáchành động
- interface
onResultsReady
như mộtcallback
để trả dữ liệu về choactivity
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 permissionsSpeechRecognizer.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ộtSpeechRecognizerManager
với 2 tham số Context và onResultsReady - Trong
constructor
của SpeechRecognizerManager, chúng ta tạo mới mộtSpeechRecognizer
sử dụngSpeechRecognitionListener
ở trên. Tiếp theo tạo mộtIntent
vàstartListening
. Thế là xong @@
Code: các bạn có thể check full code ở SpeechRecognizerManager.java
All rights reserved