A entrada de texto por voz permite criar uma interface verdadeiramente viva-voz. Vidro oferece três maneiras de utilizar a entrada de texto por voz.
Os principais comandos de voz iniciam o Glassware a partir do card "Início", voz contextual comandos podem executar ações em uma atividade, e a fala do sistema a atividade de reconhecimento permite que você receba entradas de voz em formato livre dos usuários.
Principais comandos de voz
Esses comandos de voz iniciam o Glassware pelo card "Início" (card de relógio). Quando você declarar um comando de voz principal, o Google Glass cria automaticamente um item de menu de toque. como substituto se os usuários decidirem iniciar seu Glassware tocando no Card inicial.
Para adicionar um comando de voz ao menu principal de voz do ok Glass, siga estas etapas:
Crie um recurso XML para o comando de voz em
res/xml/<my_voice_trigger>.xml
que usa um dos comandos de voz existentes definido emVoiceTriggers.Command
. Por exemplo, veja como usar "Iniciar uma corrida".<?xml version="1.0" encoding="utf-8"?> <trigger command="START_A_RUN" />
Para criar um comando de voz que peça para o usuário falar mais uma vez antes de iniciar a atividade ou o serviço, inclua um
input
também é um elemento desse tipo. Por exemplo, você pode fazer isso se estiver usando "Postar uma atualização".<?xml version="1.0" encoding="utf-8"?> <trigger command="POST_AN_UPDATE"> <input prompt="@string/glass_voice_prompt" /> </trigger>
Registrar um filtro de intent usando o
com.google.android.glass.action.VOICE_TRIGGER
ação na sua manifesto do Android. O filtro de intent inicia sua atividade ou serviço se detectar usuários falando o comando de voz.<?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>
Declare um atributo
android:icon
para sua atividade ou serviço. Isso permite que o Google Glass exiba um ícone para seu Glassware no Ok, vidro do menu de toque.<activity |service android:icon="@drawable/my_icon" ...> ... </activity | service>
Se o seu comando de voz usar uma solicitação de voz e iniciar uma atividade, obtenha qualquer texto transcrito com o seguinte código (como em
onResume()
):ArrayList<String> voiceResults = getIntent().getExtras() .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
Se o comando de voz iniciar um serviço, o extra da intent estará disponível no Callback
onStartCommand()
:@Override public int onStartCommand(Intent intent, int flags, int startId) { ArrayList<String> voiceResults = intent.getExtras() .getStringArrayList(RecognizerIntent.EXTRA_RESULTS); // ... }
Como definir restrições
Se você precisar de um ou todos os seguintes recursos para iniciar seu Glassware,
especificá-las no recurso res/xml/<my_voice_trigger>.xml
.
Se os recursos não estiverem disponíveis, o Google Glass desativará o comando de voz:
camera
network
microphone
<trigger command="POST_AN_UPDATE"> <constraints camera="true" network="true" /> </trigger>
Comandos de voz contextuais
Os comandos de voz contextuais permitem que os usuários realizem ações em atividades. Você cria comandos de voz contextuais com as APIs de menu padrão do Android, mas os usuários podem invocar os itens de menu com comandos de voz em vez de toque.
Para ativar comandos de voz contextuais para uma atividade específica:
Ligue para
getWindow().requestFeature(
WindowUtils.FEATURE_VOICE_COMMANDS
)
na atividade desejada para ativar comandos de voz contextuais. Com esse recurso ativado, o menu "ok Glass" será exibido no rodapé da tela sempre que essa atividade receber foco.Substituir
onCreatePanelMenu()
e lidar com o caso em queWindowUtils.FEATURE_VOICE_COMMANDS
está ativado. Se ativado, é aqui que você configura o menu uma única vez, como inflar um recurso de menu ou chamar o métodoMenu.add()
métodos para criar seu sistema de menus de voz.Substituir
onMenuItemSelected()
para lidar com os comandos de voz quando os usuários os falam. Quando os usuários concluírem a seleção de um item de menu, o comando de voz "ok, Glass" automaticamente reaparece na seção de rodapé da tela, pronta para aceitar uma nova voz contanto que a atividade permaneça em foco.O código a seguir ativa comandos de voz contextuais e infla um recurso de menu quando apropriado, e lida com comandos de voz quando eles são falados:
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); } }
Aqui está um exemplo do recurso de menu usado pela atividade anterior. É possível criar itens de menu aninhados para uma voz hierárquica sistema de menus. No exemplo a seguir, o primeiro item de menu pode ser acessado como: ok Glass, Mostre-me cachorros, 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>
(Opcional) Substituir
onPreparePanel()
, verificar seWindowUtils.FEATURE_VOICE_COMMANDS
está ativado. Se ativado, é possível usar outra lógica para configurar o sistema de menus, como adicionar e remover certos itens do menu com base em critérios. Você pode ativar (voltartrue
) e desativar os menus de voz contextuais (retornarfalse
) com base em alguns critérios. Exemplo: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); }
Compatibilidade com menus de voz e toque simultaneamente
Como os comandos de voz contextuais usam as APIs de menu existentes do Android, é possível reutilizar boa parte do código e dos recursos que já tem para menus de toque e, ao mesmo tempo, oferecer suporte aos dois tipos de menu.
Tudo o que você precisa fazer é procurar o recurso Window.FEATURE_OPTIONS_PANEL
além do recurso WindowUtils.FEATURE_VOICE_COMMANDS
que você já
estão verificando em alguns métodos e, em seguida, acrescentando lógica para abrir
em alguma ação do usuário, como um toque.
Por exemplo, você pode mudar a atividade anterior exemplo para adicionar suporte para menus de toque como este (as alterações são comentadas):
// 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) {
...
}
Com essas mudanças, você pode tocar ou dizer ok copo para exibir seu cardápio.
Usar comandos de voz não listados para desenvolvimento
Para distribuir seu Glassware, você precisa usar a versão principal aprovada
comandos de voz em
VoiceTriggers.Command
e aprovados nos comandos de voz contextuais
ContextualMenus.Command
Se você quiser usar comandos de voz que não estão disponíveis no GDK,
solicite uma permissão do Android no arquivo AndroidManifest.xml
:
<uses-permission
android:name="com.google.android.glass.permission.DEVELOPMENT" />
Usar os principais comandos de voz não listados
Declare um valor de string em
res/values/strings.xml
que defina o nome do seu gatilho de voz. Como opção, declare uma solicitação de voz para exibir o Glassware de reconhecimento de fala antes de iniciá-lo.<?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>
Crie um recurso XML para o gatilho de voz em
res/xml/<my_voice_trigger>.xml
: Para comandos de voz não listados, use o atributokeyword
em vez do atributocommand
usado para anúncios comandos de voz. O atributokeyword
precisa ser uma referência à string que define o comando de voz. Para um acionador de voz simples que inicia uma atividade ou serviço imediatamente, basta especificar o elementotrigger
:<?xml version="1.0" encoding="utf-8"?> <trigger keyword="@string/glass_voice_trigger" />
Para criar um gatilho de voz que peça que o usuário fale mais uma vez antes de iniciar sua atividade ou serviço, inclua um elemento de entrada também:
<?xml version="1.0" encoding="utf-8"?> <trigger keyword="@string/glass_voice_trigger"> <input prompt="@string/glass_voice_prompt" /> </trigger>
Usar comandos de voz contextuais não listados
Ao criar itens de menu, use qualquer texto para o título do item. Exemplo:
<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>
Iniciando reconhecimento de fala
O Glassware de reconhecimento de fala espera que os usuários falem e retorna o após a conclusão do texto transcrito. Para iniciar a atividade:
- Chamar
startActivityForResult()
com a intentACTION_RECOGNIZE_SPEECH
. Os extras de intent abaixo têm suporte ao iniciar a atividade: Substitua o
onActivityResult()
para receber o texto transcrito doEXTRA_RESULTS
de intent extra. Esse callback é chamado quando o usuário termina de falar.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); }