Nhập bằng giọng nói

Nhập liệu bằng giọng nói cho phép bạn tạo một giao diện thực sự rảnh tay. Ly cung cấp cho bạn 3 cách để sử dụng tính năng nhập bằng giọng nói.

Các lệnh thoại chính khởi động Glassware từ thẻ Trang chủ, giọng nói theo bối cảnh các lệnh có thể thực thi thao tác trong một hoạt động và giọng nói của hệ thống hoạt động nhận dạng cho phép bạn nhận dữ liệu nhập bằng giọng nói dạng tự do từ người dùng.

Lệnh thoại chính

Các lệnh thoại này khởi chạy Glassware từ thẻ Màn hình chính (thẻ Đồng hồ). Khi khai báo lệnh thoại chính, Glass sẽ tự động tạo một mục trong trình đơn cảm ứng làm phương án dự phòng nếu người dùng quyết định bắt đầu Đồ thuỷ tinh của bạn bằng cách nhấn vào Thẻ nhà.

Cách thêm lệnh thoại vào trình đơn chính bằng giọng nói ok Glass:

  1. Tạo tài nguyên XML cho lệnh thoại trong res/xml/<my_voice_trigger>.xml sử dụng một trong các lệnh thoại hiện có được xác định trong VoiceTriggers.Command. Ví dụ: sau đây là cách sử dụng "Bắt đầu chạy".

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="START_A_RUN" />
    

    Để tạo một lệnh thoại nhắc người dùng nói thêm trước khi bắt đầu hoạt động hoặc dịch vụ của bạn, hãy thêm input . Ví dụ: bạn có thể muốn thực hiện việc này nếu bạn bằng cách sử dụng mục "Đăng nội dung cập nhật".

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="POST_AN_UPDATE">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    
  2. Đăng ký một bộ lọc ý định bằng cách sử dụng com.google.android.glass.action.VOICE_TRIGGER hành động trong Tệp kê khai Android. Bộ lọc ý định bắt đầu hoạt động hoặc dịch vụ của bạn nếu phát hiện thấy người dùng nói lệnh thoại của bạn.

    <?xml version="1.0" encoding="utf-8"?>
    <application ...>
        <activity | service ...>
            <intent-filter>
                <action android:name=
                        "com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/my_voice_trigger" />
        </activity | service>
        // ...
    </application>
    
  3. Khai báo thuộc tính android:icon cho hoạt động hoặc dịch vụ. Điều này cho phép Glass hiển thị biểu tượng cho Đồ thuỷ tinh của bạn trong ok, hãy thuỷ tinh trên trình đơn cảm ứng.

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. Nếu lệnh thoại của bạn sử dụng lời nhắc bằng giọng nói và bắt đầu một hoạt động, hãy lấy bất kỳ văn bản được chép lời nào có mã sau đây (chẳng hạn như trong onResume()):

    ArrayList<String> voiceResults = getIntent().getExtras()
            .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
    

    Nếu lệnh thoại bắt đầu một dịch vụ, thì ý định bổ sung sẽ có trong Lệnh gọi lại onStartCommand():

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ArrayList<String> voiceResults = intent.getExtras()
                .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
        // ...
    }
    

Đặt điều kiện ràng buộc

Nếu bạn cần một hoặc tất cả các tính năng sau để khởi động Đồ thuỷ tinh, chỉ định chúng trong tài nguyên res/xml/<my_voice_trigger>.xml. Nếu các tính năng này không hoạt động, Glass sẽ tắt lệnh thoại:

  • camera
  • network
  • microphone

    <trigger command="POST_AN_UPDATE">
        <constraints
            camera="true"
            network="true" />
    </trigger>
    

Lệnh thoại theo ngữ cảnh

Lệnh thoại theo ngữ cảnh cho phép người dùng thực hiện thao tác trong các hoạt động. Bạn tạo lệnh thoại theo ngữ cảnh bằng các API trình đơn Android chuẩn nhưng người dùng có thể gọi các mục trong trình đơn bằng lệnh thoại thay vì chạm.

Để bật lệnh thoại theo ngữ cảnh cho một hoạt động cụ thể, hãy làm như sau:

  1. Gọi getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) trong hoạt động mong muốn để bật lệnh thoại theo ngữ cảnh. Với tính năng này đã bật, trình đơn "ok Glass" sẽ xuất hiện ở khu vực chân trang của màn hình bất cứ khi nào hoạt động này nhận được tiêu điểm.

  2. Ghi đè onCreatePanelMenu() và xử lý trường hợp khi WindowUtils.FEATURE_VOICE_COMMANDS đã được bật. Nếu đã bật thì đây sẽ là nơi bạn thiết lập trình đơn một lần, chẳng hạn như mở rộng tài nguyên trình đơn hoặc gọi Menu.add() để tạo hệ thống trình đơn bằng giọng nói.

  3. Ghi đè onMenuItemSelected() để xử lý các lệnh thoại khi người dùng nói chúng. Khi người dùng hoàn tất chọn một mục trong trình đơn, lệnh thoại "ok, Glass" sẽ tự động được thiết lập xuất hiện lại ở phần chân trang của màn hình và sẵn sàng chấp nhận giọng nói mới , miễn là hoạt động vẫn nằm trong tiêu điểm.

    Mã sau đây kích hoạt lệnh thoại theo ngữ cảnh, tăng cường tài nguyên trình đơn khi thích hợp và xử lý lệnh thoại khi chúng được nói:

    public class ContextualMenuActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle bundle) {
            super.onCreate(bundle);
    
            // Requests a voice menu on this activity. As for any other
            // window feature, be sure to request this before
            // setContentView() is called
            getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS);
            setContentView(R.layout.activity_main);
        }
    
        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu) {
            if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
            }
            // Pass through to super to setup touch menu.
            return super.onCreatePanelMenu(featureId, menu);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item) {
            if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
                switch (item.getItemId()) {
                    case R.id.dogs_menu_item:
                        // handle top-level dogs menu item
                        break;
                    case R.id.cats_menu_item:
                        // handle top-level cats menu item
                        break;
                    case R.id.lab_menu_item:
                        // handle second-level labrador menu item
                        break;
                    case R.id.golden_menu_item:
                        // handle second-level golden menu item
                        break;
                    case R.id.calico_menu_item:
                        // handle second-level calico menu item
                        break;
                    case R.id.cheshire_menu_item:
                        // handle second-level cheshire menu item
                        break;
                    default:
                        return true;
                }
                return true;
            }
            // Good practice to pass through to super if not handled
            return super.onMenuItemSelected(featureId, item);
        }
    }
    

    Dưới đây là ví dụ về tài nguyên trình đơn mà hoạt động trước đó sử dụng. Lưu ý cách bạn có thể tạo các mục trong trình đơn lồng nhau cho giọng nói phân cấp hệ thống trình đơn. Trong ví dụ sau, mục đầu tiên trong trình đơn có thể có thể truy cập là: ok Glass, Cho tôi xem những chú chó, Labrador.

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Use the constants defined in the ContextualMenus.Command enum-->
        <item
            android:id="@+id/dogs_menu_item"
            android:title="@string/show_me_dogs">
            <menu>
                <item
                    android:id="@+id/lab_menu_item"
                    android:title="@string/labrador" />
                <item
                    android:id="@+id/golden_menu_item"
                    android:title="@string/golden" />
            </menu>
        </item>
        <item
            android:id="@+id/cats_menu_item"
            android:title="@string/show_me_cats">
            <menu>
                <item
                    android:id="@+id/cheshire_menu_item"
                    android:title="@string/cheshire" />
                <item
                    android:id="@+id/calico_menu_item"
                    android:title="@string/calico" />
            </menu>
        </item>
    </menu>
    
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Use the constants defined in the ContextualMenus.Command enum-->
        <item
            android:id="@+id/play_menu_item"
            android:title="PLAY_MUSIC" />
        <item
            android:id="@+id/pause_menu_item"
            android:title="PAUSE_MUSIC" />
    </menu>
    
  4. (Không bắt buộc) Ghi đè onPreparePanel()! đang kiểm tra xem có WindowUtils.FEATURE_VOICE_COMMANDS đã được bật. Nếu được bật, đây là nơi bạn có thể thực hiện logic khác để thiết lập hệ thống trình đơn, chẳng hạn như thêm và xoá các mục nhất định trong trình đơn dựa trên một số tiêu chí. Bạn có thể cũng bật và tắt trình đơn giọng nói theo ngữ cảnh (trả lại true) (trả về false) dựa trên một số tiêu chí. Ví dụ:

        private boolean mVoiceMenuEnabled;
        ...
        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu) {
            if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
            // toggle this boolean on and off based on some criteria
                return mVoiceMenuEnabled;
            }
            // Good practice to call through to super for other cases
            return super.onPreparePanel(featureId, view, menu);
        }
    

Hỗ trợ đồng thời các trình đơn cảm ứng và giọng nói

Vì lệnh thoại theo ngữ cảnh sử dụng API trình đơn hiện có của Android, bạn có thể sử dụng lại nhiều mã và tài nguyên bạn đã có cho trình đơn cảm ứng đồng thời hỗ trợ cả hai loại trình đơn.

Bạn chỉ cần kiểm tra để tìm tính năng Window.FEATURE_OPTIONS_PANEL cùng với tính năng WindowUtils.FEATURE_VOICE_COMMANDS mà bạn đã đang kiểm tra trong một vài phương thức và sau đó thêm logic để mở tính năng cảm ứng vào một số thao tác của người dùng, chẳng hạn như nhấn.

Ví dụ: bạn có thể thay đổi hoạt động trước đó ví dụ về cách thêm tính năng hỗ trợ cho các trình đơn cảm ứng như thế này (có nhận xét về các thay đổi):

// 1. Check for Window.FEATURE_OPTIONS_PANEL
// to inflate the same menu resource for touch menus.
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
            featureId == Window.FEATURE_OPTIONS_PANEL) {
    ...
}

// 2. Check for Window.FEATURE_OPTIONS_PANEL
// to handle touch menu item selections.
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
            featureId == Window.FEATURE_OPTIONS_PANEL) {
    ...
}

Với những thay đổi này, bạn có thể nhấn hoặc nói OK kính để hiển thị thực đơn của bạn.

Sử dụng lệnh thoại không công khai để phát triển ứng dụng

Khi muốn phân phối Đồ thuỷ tinh của mình, bạn phải sử dụng lệnh thoại trong VoiceTriggers.Command và lệnh thoại theo ngữ cảnh đã được phê duyệt trong ContextualMenus.Command.

Nếu bạn muốn sử dụng lệnh thoại không có trong GDK, bạn có thể yêu cầu quyền trên Android trong tệp AndroidManifest.xml:

<uses-permission
     android:name="com.google.android.glass.permission.DEVELOPMENT" />

Sử dụng lệnh thoại chính không công khai

  1. Khai báo một giá trị chuỗi trong res/values/strings.xml giúp xác định tên của lệnh kích hoạt bằng giọng nói. Tùy ý khai báo lời nhắc bằng giọng nói để hiển thị Đồ thuỷ tinh nhận dạng lời nói trước khi khởi động Đồ thuỷ tinh của bạn.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="glass_voice_trigger">read me a story</string>
        <string name="glass_voice_prompt">what story?</string>
    </resources>
    
  2. Tạo tài nguyên XML cho trình kích hoạt giọng nói trong res/xml/<my_voice_trigger>.xml. Đối với các lệnh thoại không công khai, bạn nên sử dụng thuộc tính keyword thay vì thuộc tính command dùng để phê duyệt lệnh thoại. Thuộc tính keyword phải là tham chiếu đến chuỗi xác định lệnh thoại. Đối với một trình kích hoạt bằng giọng nói đơn giản khởi động hoạt động hoặc dịch vụ ngay lập tức, bạn chỉ cần chỉ định phần tử trigger:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger" />
    

    Để tạo điều kiện kích hoạt bằng giọng nói nhắc người dùng nói thêm trước khi bắt đầu hoạt động hoặc dịch vụ của bạn, hãy thêm phần tử đầu vào cũng như:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    

Sử dụng lệnh thoại theo ngữ cảnh không công khai

Khi tạo các mục trong trình đơn, hãy sử dụng văn bản bất kỳ cho tiêu đề của mục trong trình đơn. Ví dụ:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Use the constants defined in the ContextualMenus.Command enum-->
    <item
        android:id="@+id/pizza_menu_item"
        android:title="@string/find_pizza" />
</menu>

Bắt đầu nhận dạng giọng nói


Tính năng nhận dạng lời nói Glassware chờ người dùng nói và trả về văn bản được chép lời sau khi viết xong. Để bắt đầu hoạt động này, hãy làm như sau:

  1. Gọi startActivityForResult() với ý định ACTION_RECOGNIZE_SPEECH. Các ý định bổ sung sau đây được hỗ trợ khi khởi động hoạt động:
  2. Ghi đè onActivityResult() để nhận văn bản chép lời từ EXTRA_RESULTS ý định bổ sung. Lệnh gọi lại này được gọi khi người dùng nói xong.

    private static final int SPEECH_REQUEST = 0;
    
    private void displaySpeechRecognizer() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        startActivityForResult(intent, SPEECH_REQUEST);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
            List<String> results = data.getStringArrayListExtra(
                    RecognizerIntent.EXTRA_RESULTS);
            String spokenText = results.get(0);
            // Do something with spokenText.
        }
        super.onActivityResult(requestCode, resultCode, data);
    }