الإدخال الصوتي

يتيح لك الإدخال الصوتي إنشاء واجهة بدون استخدام اليدين. يمنحك Glass ثلاث طرق لاستخدام الإدخال الصوتي.

تبدأ الأوامر الصوتية الرئيسية Glassware من بطاقة Home، ويمكن للأوامر الصوتية السياقية تنفيذ إجراءات ضمن أحد الأنشطة، ويسمح لك نشاط التعرُّف على الكلام في النظام بتلقي إدخال صوتي حر من المستخدمين.

الطلبات الصوتية الرئيسية

تؤدي هذه الأوامر الصوتية إلى تشغيل Glassware من بطاقة Home (بطاقة الساعة). عندما تعلن عن أمر صوتي رئيسي، ينشئ Glass عنصر قائمة لمس تلقائيًا كعنصر احتياطي إذا قرر المستخدمون بدء تشغيل Glassware بالنقر على بطاقة Home.

لإضافة أمر صوتي إلى القائمة الصوتية الرئيسية 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. سجِّل فلتر الأهداف باستخدام الإجراء com.google.android.glass.action.VOICE_TRIGGER في ملف بيان Android. يبدأ فلتر الأهداف نشاطك أو خدمتك في حال رصد مستخدمين يتكلّمون أمرك الصوتي.

    <?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 بعرض رمز للأواني الزجاجية في قائمة اللمس OK, Glass.

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. إذا كان الأمر الصوتي يستخدم مطالبة صوتية ويبدأ نشاطًا، يمكنك الحصول على أي نص تم تحويله إلى نص باستخدام الرمز التالي (كما هو الحال في onResume()):

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

    في حال بدء الطلب الصوتي لخدمة، يتوفّر الإجراء الإضافي المقصود في استدعاء 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>
    

الطلبات الصوتية حسب السياق

تتيح الأوامر الصوتية حسب السياق للمستخدمين تنفيذ إجراءات من الأنشطة. يمكنك إنشاء أوامر صوتية سياقية باستخدام واجهات برمجة التطبيقات القياسية لنظام Android ولكن يمكن للمستخدمين استدعاء عناصر القائمة باستخدام الأوامر الصوتية بدلاً من اللمس.

لتمكين الأوامر الصوتية حسب السياق لنشاط معين:

  1. يمكنك استدعاء getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) في النشاط المطلوب لتفعيل الأوامر الصوتية حسب السياق. عند تمكين هذه الميزة، تظهر القائمة "ok Glass" في منطقة تذييل الشاشة عندما يتلقى هذا النشاط تركيزًا.

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

دعم قوائم الصوت واللمس في آنٍ واحد

ونظرًا لأن الأوامر الصوتية السياقية تستخدم واجهات برمجة تطبيقات قائمة 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) {
    ...
}

بعد تطبيق هذه التغييرات، يمكنك إما النقر على OK Glass أو قولها لعرض قائمتك.

استخدام الأوامر الصوتية غير المدرجة للتطوير

إذا كنت تريد توزيع Glassware، يجب استخدام الطلبات الصوتية الرئيسية المعتمدة في VoiceTriggers.Command والطلبات الصوتية المعتمدة للمحتوى في ContextualMenus.Command.

إذا كنت تريد استخدام أوامر صوتية غير متوفرة في GDK، يمكنك طلب إذن Android في ملف AndroidManifest.xml:

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

استخدام الأوامر الصوتية الرئيسية غير المدرجة

  1. اذكر قيمة سلسلة في res/values/strings.xml تحدد اسم مشغل الصوت. يمكنك اختياريًا الإعلان عن مطالبة صوتية بعرض أواني Glass Glass والتعرف على الكلام قبل بدء 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() لتلقّي النص المحوّل صوتيًا من العنصر الإضافي 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);
    }