0

Speech to text trong Android

Giới thiệu

Hôm nay, như tiêu đề đã ghi rõ, mình sẽ giới thiệu tới tất cả mọi người về 1 chức năng rất hay của Android. Đó là speech to text. Chức năng này mới nghe thì tưởng chừng rất khó, nhưng thật ra nó chỉ hơi khó thôi 😃) Và chúng ta hoàn toàn có thể đưa chức năng này vào app của riêng mình để làm phong phú thêm cho các chức năng.

Và ngay bây h chúng ta sẽ bắt đầu tìm hiểu cách thức xây dựng nên chức năng này.

  • Đầu tiên, phải nói qua cơ chế của speech to text: khi chúng ta phát âm vào máy, máy sẽ tạo ra 1 têp tin âm thanh và chuyển về một server nào đó của google và server này sẽ trả lại một mảng các chuỗi ký tự gần giống với âm thanh bạn phát ra trong tập tin đó.

  • Cho tới thời điểm này thì việc nhận dạng âm thanh chuyển đổi vẫn chưa thật chính xác lắm bởi vậy bạn phải phát âm thật chuẩn mới trả về đúng ký tự muon muốn (lưu ý có hỗ trợ tiếng Việt)

Hướng dẫn source code:

  • Để có thể sủ dụng được tính năng này, chúng ta phải được cấp quyền sử dụng Internet:

    <uses-permission android:name="android.permission.INTERNET" />

  • file layout của Activity thao tác:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:gravity="center"
        android:text="@string/parsed_data"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/etTextHint"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:hint="@string/etSearchHint"
        android:inputType="textMultiLine"
        android:lines="1" />

    <Button
        android:id="@+id/btSpeak"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="speak"
        android:padding="@dimen/padding_medium"
        android:text="@string/btSpeak"
        tools:context=".VoiceRecognitionActivity" />

- Cuối cùng là file MainActivity

```Java

    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001;

    private EditText metTextHint;
    private ListView mlvTextMatches;
    private Spinner msTextMatches;
    private Button mbtSpeak;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        metTextHint = (EditText) findViewById(R.id.etTextHint);
        mlvTextMatches = (ListView) findViewById(R.id.lvTextMatches);
        msTextMatches = (Spinner) findViewById(R.id.sNoOfMatches);
        mbtSpeak = (Button) findViewById(R.id.btSpeak);

        checkVoiceRecognition();
    }

    public void checkVoiceRecognition() {
        Log.v("", "checkVoiceRecognition checkVoiceRecognition");
        // Kiem tra thiet bi cho phep nhan dang giong noi hay ko
        PackageManager pm = getPackageManager();
        List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
        if (activities.size() == 0) {
            mbtSpeak.setEnabled(false);
            Toast.makeText(this, "Voice recognizer not present", Toast.LENGTH_SHORT).show();
        }
    }

    // Gui tap tin am thanh
    public void speak(View view) {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        // xac nhan ung dung muon gui yeu cau
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());

        // goi y nhung dieu nguoi dung muon noi
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, metTextHint.getText().toString());

        // goi y nhan dang nhung gi nguoi dung se noi
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);

        // Kiem tra item muon hien thi da chon tron spinner
        if (msTextMatches.getSelectedItemPosition() == AdapterView.INVALID_POSITION) {
            Toast.makeText(this, "Please select No. of Matches from spinner", Toast.LENGTH_SHORT).show();
            return;
        }

        int noOfMatches = Integer.parseInt(msTextMatches.getSelectedItem().toString());

        // Xac dinh ban muon bao nhieu ket qua gan dung duoc tra ve
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, noOfMatches);

        // Gui yeu cau di
        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
    }

    // Su kien nhan lai ket qua
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == VOICE_RECOGNITION_REQUEST_CODE)

            // Truong hop co gia tri tra ve
            if(resultCode == RESULT_OK) {
                ArrayList<String> textMatchList = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

                if (!textMatchList.isEmpty()) {
                    // kiem tra neu co chua tu khoa 'search' thi se bat dau tim kiem tren web
                    if (textMatchList.get(0).contains("search")) {
                        String searchQuery = textMatchList.get(0).replace("search", " ");
                        Intent search = new Intent(Intent.ACTION_WEB_SEARCH);
                        search.putExtra(SearchManager.QUERY, searchQuery);
                        startActivity(search);
                    } else {
                        // Hien thi ket qua
                        mlvTextMatches.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, textMatchList));
                    }
                }
            // Cac truong hop loi
            } else if (resultCode == RecognizerIntent.RESULT_AUDIO_ERROR){
                showToastMessage("Audio Error");
            } else if (resultCode == RecognizerIntent.RESULT_CLIENT_ERROR){
                showToastMessage("Client Error");
            } else if (resultCode == RecognizerIntent.RESULT_NETWORK_ERROR){
                showToastMessage("Network Error");
            } else if (resultCode == RecognizerIntent.RESULT_NO_MATCH){
                showToastMessage("No Match");
            } else if (resultCode == RecognizerIntent.RESULT_SERVER_ERROR){
                showToastMessage("Server Error");
            }
        super.onActivityResult(requestCode, resultCode, data);
    }

    void showToastMessage(String message){
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí