【问题标题】:How to Navigate a Google Glass GDK Immersion Application using Voice Command only?如何仅使用语音命令导航 Google Glass GDK 沉浸式应用程序?
【发布时间】:2014-03-06 07:34:05
【问题描述】:

如何编写语音触发器来导航 Google Glass Card?

This is how I see it happening:

1) "Ok Glass, Start My Program"

2) Application begins and shows the first card

3) User can say "Next Card" to move to the next card 
(somewhat the equivalent of swiping forward when in the timeline)

4) User can say "Previous Card" to go back 

我需要显示的卡片是简单的文本和图像,我想知道是否可以设置某种类型的监听器来在显示卡片时收听语音命令。


我研究了Glass voice command nearest match from given list,但无法运行代码,尽管我拥有所有库。

旁注:用户在使用语音命令时仍能看到卡片,这一点很重要。他的手也很忙,所以不能点击/滑动。

关于如何在我的 Immersion 应用中仅使用语音控制来控制时间线的任何想法?将不胜感激!

我也在跟踪https://code.google.com/p/google-glass-api/issues/detail?id=273


我正在进行的研究让我回顾了 Google Glass Developer 以使用 Google 建议的聆听手势的方式:https://developers.google.com/glass/develop/gdk/input/touch#detecting_gestures_with_a_gesture_detector

我们如何通过语音命令激活这些手势?


Android 刚刚发布了 beta 版可穿戴设备升级,适用于 android http://developer.android.com/wear/notifications/remote-input.html,有什么方法可以用来回答我的问题吗?感觉我们仍然距离我们还有 1 步之遥,因为我们可以调用该服务,但在我们交谈时不能让它作为后台服务“休眠”和“唤醒”。

【问题讨论】:

  • 您提供的 S-O 答案的链接对我来说非常有效,并且完全符合您所追求的功能。你有什么问题?您是在卡片滚动视图中执行此操作吗?
  • 你有没有想过这个问题?我正在尝试做一些非常相似的事情
  • 还没有,我希望下一次 Glass 更新将包含该功能 - 如果他们希望人们采用 Glass,这确实是必须的。我们需要和 Glass 谈谈。

标签: android google-glass google-gdk


【解决方案1】:

这个东西在onCreate方法中定义

mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 
    //  mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);

    sr = SpeechRecognizer.createSpeechRecognizer(context);       
    sr.setRecognitionListener(new listener(context));   

    //      intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
    intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);        
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,context.getPackageName());
    sr.startListening(intent);
    Log.i("111111","11111111"+"in");

这个监听器类只是添加到你的类中

class  listener implements RecognitionListener          
{
    Context context1;
    public listener(Context context)
    {
        //Log.i("onError startListening","enter"+"nam");
        context1=context;
    }
    public void onReadyForSpeech(Bundle params)
    {
        //Log.d(TAG, "onReadyForSpeech");
    }
    public void onBeginningOfSpeech()
    {
        //Log.d(TAG, "onBeginningOfSpeech");
    }
    public void onRmsChanged(float rmsdB)
    {
        //Log.d(TAG, "onRmsChanged");
    }
    public void onBufferReceived(byte[] buffer)
    {
        //Log.d(TAG, "onBufferReceived");
    }
    public void onEndOfSpeech()
    {
        //Log.d(TAG, "onEndofSpeech");
        sr.startListening(intent);
    }
    public void onError(int error)
    {
        //Log.d(TAG,  "error " +  error);
        //7 -No recognition result matched.
        //9 - vInsufficient permissions 
        //6 - No speech input 
        //8 RecognitionService busy. 
        //5 Other client side errors. 
        //3 Audio recording error.  
        //  mText.setText("error " + error);

        if(error==6 || error==7 || error==4  || error==1 || error==2 || error==5 || error==3 || error==8 || error==9 )
        { 
            sr.startListening(intent);
            //Log.i("onError startListening","onError startListening"+error);
        }
    }
    public void onResults(Bundle results)                   
    {
        //Log.v(TAG,"onResults" + results);
        ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        for (int i = 0; i < data.size(); i++)
        {
            //Log.d(TAG, "result " + data.get(i));
            //str += data.get(i);

        //Toast.makeText(context1, "results: "+data.get(0).toString(), Toast.LENGTH_LONG).show();
        //Log.v("my", "output"+"results: "+data.get(0).toString());

        //sr.startListening(intent);
                   }
    }
    public void onPartialResults(Bundle partialResults)
    {
        //Log.d(TAG, "onPartialResults");
    }
    public void onEvent(int eventType, Bundle params)
    {
        //Log.d(TAG, "onEvent " + eventType);
    }
}

【讨论】:

【解决方案2】:

【讨论】:

    【解决方案3】:

    您可能想尝试 GDK 中提供的上下文语音命令。虽然它确实用菜单暂时覆盖了屏幕,但它只允许语音输入。

    https://developers.google.com/glass/develop/gdk/voice

    【讨论】:

    • 是的,但是目的是让外科医生在查看他正在做什么的同时解放双手,上下文语音命令需要作为后台服务运行,我正在尝试原型 - 将得到很快回来
    【解决方案4】:

    我为我的一个应用程序做了非常相似的事情。它根本不需要ok玻璃屏幕,但用户确实需要提前知道命令。我解释了一点,并提供了关于这个问题的链接:在这里查看我的答案:Glass GDk : Contextual voice commands without the "Ok Glass"

    我希望这会有所帮助!

    【讨论】:

    • 我会调查并通知您,谢谢!很久没有解决方案了。
    • 我尝试运行你的代码,但由于我没有 root 我的设备,我无法安装 python。你碰巧有一个没有 python 的语音识别示例吗?我无法测试您的代码(看起来可以正常工作)。谢谢!
    • @Loadparts python 代码用于通过蓝牙连接到 Glass 的计算机。你想要 android 目录中的代码。无需安装pythongithub.com/RIVeR-Lab/google_glass_driver/tree/master/android/…
    • ^如果你不介意等一天,我可能会整理一个开箱即用的演示,让你玩它
    • 难道没有办法让你用它来制作图书馆吗?我敢打赌,这会帮助很多人,并且每个人都更容易实际使用它。只是一个想法,因为我试图让类似的东西工作。
    【解决方案5】:

    我正在详细写出整个代码,因为我花了这么长时间才让它工作..也许它会节省其他人宝贵的时间。

    此代码是 Google 上下文语音命令的实现,如 Google Developers 所述:Contextual voice commands

    ContextualMenuActivity.java

       package com.drace.contextualvoicecommands;
    
        import android.app.Activity;
        import android.os.Bundle;
        import android.view.Menu;
        import android.view.MenuItem;
        import com.drace.contextualvoicecommands.R;
        import com.google.android.glass.view.WindowUtils;
    
        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);
        }
        }
    

    activity_main.xml(布局)

     <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout 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" >
    
              <TextView
            android:id="@+id/coming_soon"
            android:layout_alignParentTop="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/voice_command_test"
            android:textSize="22sp"
            android:layout_marginRight="40px"
            android:layout_marginTop="30px"
            android:layout_marginLeft="210px" /> 
        </RelativeLayout>
    

    strings.xml

    <resources>
    <string name="app_name">Contextual voice commands</string>
    <string name="voice_start_command">Voice commands</string>
    <string name="voice_command_test">Say "Okay, Glass"</string>
    <string name="show_me_dogs">Dogs</string>
    <string name="labrador">labrador</string>
    <string name="golden">golden</string>
    <string name="show_me_cats">Cats</string>
    <string name="cheshire">cheshire</string>
    <string name="calico">calico</string>
    </resources>
    

    AndroidManifest.xml

     <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.drace.contextualvoicecommands"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="19"
            android:targetSdkVersion="19" />
    
        <uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT"/>
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
    
           <activity
                android:name="com.drace.contextualvoicecommands.ContextualMenuActivity"
                android:label="@string/app_name" >
                <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/voice_trigger_start" />
            </activity>
    
        </application>
        </manifest>
    

    它已经过测试,在 Google Glass XE22 下运行良好!

    【讨论】:

    • 我想说这不是您自己问题的确切答案,因为这仍然需要您在应用程序中说“ok glass”,然后才能发出任何其他命令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多