קלט קולי

הקלט הקולי מאפשר לך ליצור ממשק ללא שימוש בידיים. Glass מספקות שלוש דרכים לשימוש בקלט קולי.

פקודות קוליות עיקריות מפעילות את Glassware מכרטיס דף הבית, פקודות קוליות לפי הקשר יכולות לבצע פעולות בתוך פעילות, ופעילות זיהוי הדיבור של המערכת מאפשרת לך לקבל קלט קולי בחופשיות ממשתמשים.

פקודות קוליות עיקריות

הפקודות הקוליות האלה מפעילות את Glassware מכרטיס Home (כרטיס שעון). אם אתם מצהירים על פקודה קולית ראשית, Glass יוצר באופן אוטומטי פריט בתפריט מגע כגיבוי, אם המשתמשים מחליטים להפעיל את Glassware על ידי הקשה על כרטיס דף הבית.

כדי להוסיף פקודה קולית לתפריט הראשי של ok glass:

  1. יוצרים משאב XML לפקודה הקולית ב-res/xml/<my_voice_trigger>.xml, שמשתמש באחת מהפקודות הקוליות הקיימות שהוגדרו ב-VoiceTriggers.Command. לדוגמה, כך משתמשים באפשרות "התחלת ריצה".

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

    כדי ליצור פקודה קולית שמבקשת מהמשתמש לומר ביטוי נוסף לפני התחלת הפעילות או השירות, יש לכלול גם רכיב input. לדוגמה, מומלץ לעשות זאת אם אתם משתמשים ב"פרסום עדכון".

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="POST_AN_UPDATE">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    
  2. רשמו מסנן Intent באמצעות הפעולה com.google.android.glass.action.VOICE_TRIGGER במניפסט של Android. מסנן Intent מתחיל את הפעילות או השירות שלכם אם הוא מזהה משתמשים שמדברים בפקודות הקוליות שלכם.

    <?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. יש להצהיר על מאפיין android:icon בפעילות או בשירות שלכם. הפעולה הזו מאפשרת ל-Glass להציג סמל של Glassware בתפריט אישור, Glass.

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. אם הפקודה הקולית שלכם משתמשת בהודעה קולית ומתחילה פעילות כלשהי, יש לשלוח את הטקסט המתומלל באמצעות הקוד הבא (לדוגמה: onResume()):

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

    אם הפקודה הקולית מפעילה שירות, הכוונה הנוספת זמינה בקריאה החוזרת (callback) ב-onStartCommand():

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

אילוצים של הגדרה

אם אתם זקוקים לאחת או יותר מהתכונות הבאות כדי להפעיל את Glassware, עליכם לציין אותן במשאב res/xml/<my_voice_trigger>.xml. אם התכונות לא זמינות, Glass משבית את הפקודה הקולית:

  • camera
  • network
  • microphone

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

פקודות קוליות לפי הקשר

פקודות קוליות לפי הקשר מאפשרות למשתמשים לבצע פעולות מתוך פעילויות. אתם מפתחים פקודות קוליות לפי הקשר באמצעות ממשקי ה-API הרגילים של תפריט Android, אבל משתמשים יכולים להפעיל את המנות בתפריט באמצעות פקודות קוליות במקום מגע.

כדי להפעיל פקודות קוליות לפי הקשר בפעילות מסוימת:

  1. צריך להתקשר אל getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) בפעילות הרצויה כדי להפעיל פקודות קוליות לפי הקשר. כאשר התכונה הזו מופעלת, התפריט "זכוכית מגדלת" מופיע באזור הכותרת התחתונה של המסך בכל פעם שמתבצעת פעילות מסוג זה.

  2. מבטלים את onCreatePanelMenu() ומטפלים בבעיה שבה מופעלת ההגדרה WindowUtils.FEATURE_VOICE_COMMANDS. אם האפשרות הזו מופעלת, כאן מתבצעת הגדרה חד-פעמית של התפריט, למשל באמצעות העלאה של משאב תפריט או הפעלת השיטות Menu.add() ליצירת המערכת של תפריט הקול.

  3. ביטול onMenuItemSelected() כדי לטפל בפקודות הקוליות כשהמשתמשים אומרים אותן. כשהמשתמשים מסיימים לבחור אפשרות בתפריט, הפקודה הקולית "ok, glass" מופיעה באופן אוטומטי בקטע של הכותרת התחתונה במסך, כשהיא מוכנה לקבל פקודה קולית חדשה, כל עוד הפעילות נשארת במוקד.

    הקוד הבא מאפשר פקודות קוליות לפי הקשר, מנפח את משאב התפריט כשיש צורך, ומטפל בפקודות קוליות כשהן מוקראות:

    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);
        }
    }
    

    הנה דוגמה למשאב התפריט המשמש את הפעילות הקודמת. שימו לב איך ליצור אפשרויות בתפריט מקוננות של תפריט קולי היררכי. בדוגמה הבאה, ניתן לגשת לפריט הראשון בתפריט בתור: ok glass, Show me dogs, 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. (אופציונלי) אפשר לבטל את onPreparePanel() כדי לבדוק אם השירות WindowUtils.FEATURE_VOICE_COMMANDS מופעל. אם האפשרות הזו מופעלת, תוכלו לבצע לוגיקה אחרת של הגדרת מערכת התפריטים, כמו הוספה והסרה של פריטים מסוימים בתפריט לפי קריטריונים מסוימים. אתם יכולים גם להפעיל או להשבית תפריטים קוליים לפי הקשר (החזר true) (חזרה false) בהתאם לקריטריונים מסוימים. למשל:

        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);
        }
    

תמיכה בו-זמנית בתפריטי קול ומגע

מכיוון שפקודות קוליות לפי הקשר פועלות בממשקי ה-API הקיימים של תפריט Android, ניתן לעשות שימוש חוזר בקוד ובמשאבים שכבר יש לכם בתפריטי מגע, ובו-זמנית לתמוך בשני סוגי התפריטים.

כל מה שאתם צריכים לעשות זה לחפש את התכונה Window.FEATURE_OPTIONS_PANEL בנוסף לתכונה WindowUtils.FEATURE_VOICE_COMMANDS שאתם כבר בודקים בכמה שיטות, ואז להוסיף לוגיקה לפתיחת תפריט המגע בחלק מפעולות המשתמשים, כמו הקשה.

לדוגמה, אפשר לשנות את הדוגמה הקודמת של הפעילות כדי להוסיף תמיכה בתפריטי מגע כמו אלה (השינויים נכתבו):

// 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) {
    ...
}

בעזרת השינויים האלה, תוכלו להקיש או לומר זכוכית מגדלת כדי להציג את התפריט שלכם.

שימוש בפקודות קוליות לא רשומות לפיתוח

כדי להפיץ את ה-Glassware, עליכם להשתמש בפקודות הקוליות הראשיות המאושרות ב-VoiceTriggers.Command ובפקודות הקוליות לפי הקשר שאושרו ב-ContextualMenus.Command.

אם אתם רוצים להשתמש בפקודות קוליות שאינן זמינות ב-GDK, תוכלו לבקש הרשאה ל-Android בקובץ AndroidManifest.xml:

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

שימוש בפקודות קוליות ראשיות לא רשומות

  1. יש להצהיר על ערך מחרוזת ב-res/values/strings.xml שמגדיר את שם הטריגר הקולי. אפשר להצהיר על הודעה קולית כדי להציג את זיהוי Glassware של זיהוי הדיבור לפני ההפעלה של Glassware.

    <?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. יצירת משאב XML לטריגר הקולי באפליקציה res/xml/<my_voice_trigger>.xml. בפקודות קוליות שלא מופיעות ברשימה, צריך להשתמש במאפיין keyword במקום במאפיין command שמשמש לפקודות קוליות מאושרות. המאפיין keyword צריך להיות הפניה למשאב המחרוזת שמגדיר את הפקודה הקולית. לטריגר קולי פשוט שיתחיל פעילות או שירות באופן מיידי, תוכלו פשוט לציין את הרכיב trigger:

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

    כדי ליצור טריגר קולי שיבקש מהמשתמש לומר ביטוי נוסף לפני התחלת הפעילות או השירות שלכם, הוסיפו גם אלמנט קלט:

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

שימוש בפקודות קוליות לפי הקשר שאינן רשומות

כשיוצרים פריטי תפריט, יש להשתמש בטקסט כלשהו לכותרת של המנה בתפריט. למשל:

<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>

זיהוי הדיבור מתחיל


זיהוי ה-Glassware לזיהוי דיבור ממתין למשתמשים לדבר ומחזיר את הטקסט המתומלל בסיום. כדי להתחיל בפעילות:

  1. מתקשרים אל startActivityForResult() בכוונה ACTION_RECOGNIZE_SPEECH. התוספות האפשריות הבאות נתמכות בזמן התחלת הפעילות:
  2. צריך לבטל את onActivityResult() הקריאה החוזרת (callback) כדי לקבל את הטקסט שתומלל מ-EXTRA_RESULTS כוונה נוספת. הקריאה החוזרת הזו נקראת כשמשתמשים מסיימים לדבר.

    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);
    }