1. Visão geral
No codelab anterior, você usou atalhos estáticos para implementar intents integradas (BIIs, na sigla em inglês) usadas com frequência em um app de exemplo. Os desenvolvedores Android utilizam as Ações no app para integrar uma funcionalidade do app ao Google Assistente.
Os atalhos estáticos são incluídos em um app e só podem ser atualizados com o lançamento de novas versões dele. A ativação dos comandos de voz para elementos dinâmicos em um app, como conteúdo gerado pelo usuário, é realizada com atalhos dinâmicos. Os apps enviam atalhos dinâmicos depois que as pessoas realizam ações relevantes, como criar uma observação em um aplicativo de rastreamento de tarefas. Com as Ações no app, você ativa comandos de voz nesses atalhos vinculando cada um deles a uma BII. Assim, os usuários podem acessar o conteúdo do Google Assistente dizendo algo como Ok Google, abra minha lista de compras no AppDeExemplo.
Figura 1. Três telas progressivas que mostram uma tarefa criada pelo usuário e o Google Assistente iniciando um atalho dinâmico para a tarefa.
O que você vai criar
Neste codelab, você vai ativar comandos de voz nos atalhos dinâmicos em um app de lista de tarefas para Android, permitindo que os usuários peçam ao Google Assistente para abrir os itens da lista criados no aplicativo. Basta usar os padrões de arquitetura do Android, especificamente aqueles do repositório, do localizador de serviços e da classe ViewModel.
Pré-requisitos
Este codelab usa os conceitos das Ações no app estudados no codelab anterior, principalmente sobre BIIs e atalhos estáticos. Se você não conhece bem as Ações no app, recomendamos concluir aquele codelab antes de continuar.
Além disso, verifique se o ambiente de desenvolvimento tem a seguinte configuração:
- Um terminal para executar comandos do shell com git instalado.
- A versão estável mais recente do Android Studio.
- Um dispositivo Android físico ou virtual com acesso à Internet.
- Uma Conta do Google conectada ao Android Studio, ao Google app e ao Assistente.
2. Como funciona
Para ativar comandos de voz em um atalho dinâmico:
- Vincule um atalho dinâmico a uma BII qualificada.
- Permita ao Assistente ingerir os atalhos adicionando a biblioteca Google Shortcuts Integration.
- Envie um atalho sempre que alguém concluir uma tarefa relevante no app.
Vincular atalhos
O Google Assistente só consegue acessar atalhos dinâmicos vinculados a BIIs relevantes. Quando uma BII com um atalho é acionada, o Google Assistente associa os parâmetros no pedido do usuário às palavras-chave definidas no atalho vinculado. Exemplo:
- Um atalho vinculado à BII
GET_THING
permite que os usuários solicitem conteúdo no app diretamente do Assistente. Por exemplo, Ok Google, abra minha lista de compras no AppDeExemplo. - Um atalho vinculado à BII
ORDER_MENU_ITEM
permite que os usuários façam o mesmo pedido novamente. Por exemplo, Ok Google, peça o de sempre no AppDeExemplo.
Acesse a referência de intents integradas para consultar a lista completa e categorizada de BIIs.
Criar atalhos para o Google Assistente
Depois de vincular os atalhos a uma BII, a próxima etapa é permitir ao Google Assistente ingerir esses atalhos adicionando a biblioteca Google Shortcuts Integration ao seu projeto. Com ela, o Google Assistente vai reconhecer cada atalho enviado pelo app. Assim, as pessoas poderão iniciar esses atalhos usando a frase de acionamento deles.
3. Preparar seu ambiente de desenvolvimento
Este codelab usa um app de lista de tarefas para Android como exemplo. Com esse aplicativo, os usuários adicionam itens a listas, fazem pesquisas por categoria e filtram tarefas por status de conclusão. Faça o download e prepare o app de exemplo concluindo esta seção.
Fazer o download dos arquivos de base
Execute o comando a seguir para clonar o repositório do GitHub do app de exemplo:
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git
Depois, siga estas etapas para abrir o conteúdo clonado no Android Studio:
- Na caixa de diálogo Welcome to Android Studio, clique em Import project.
- Selecione a pasta em que você clonou o repositório.
Também é possível conferir uma versão do app de exemplo que representa o codelab pronto clonando a ramificação de codelab-complete
do repositório do GitHub:
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete
Atualizar o ID do app Android
Atualize o ID para identificar seu app de forma exclusiva no dispositivo de teste, evitando o erro "Duplicate package name" se o aplicativo for enviado ao Play Console. Para atualizar o ID do aplicativo, abra app/build.gradle
:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Substitua "MYUNIQUENAME" no campo applicationId
por algo exclusivo.
Adicionar dependências da API Shortcuts
Inclua as seguintes bibliotecas do Jetpack no arquivo do recurso app/build.gradle
:
app/build.gradle
dependencies {
...
// Shortcuts library
implementation "androidx.core:core:1.6.0"
implementation 'androidx.core:core-google-shortcuts:1.0.1'
...
}
Testar o app no seu dispositivo
Antes de fazer outras mudanças, teste o app de exemplo para saber o que ele oferece. Para executar o aplicativo no seu emulador:
- No Android Studio, selecione Run > Run app ou clique em Run na barra de ferramentas.
- Na caixa de diálogo Select Deployment Target, escolha um dispositivo e clique em OK. O SO recomendado é o Android 10 (nível da API – 30) ou uma versão mais recente. No entanto, as Ações no app funcionam a partir do Android 5 (nível da API – 21).
- Toque e mantenha pressionado o botão home para configurar o Google Assistente e verificar se ele está funcionando. Faça login no Google Assistente usando seu dispositivo.
Para mais informações sobre dispositivos virtuais Android, consulte Criar e gerenciar dispositivos virtuais.
Use um pouco o app para saber o que ele oferece. Toque no ícone de adição para criar uma tarefa ou utilize os itens de menu no canto superior direito para pesquisar e filtrar as tarefas por status de conclusão.
4. Criar uma classe de repositório de atalhos
Várias classes do nosso app de exemplo vão chamar a API ShortcutManagerCompat
para enviar e gerenciar atalhos dinâmicos. Para reduzir a redundância de código, você vai implementar um repositório, permitindo que as classes do projeto gerenciem com facilidade os atalhos dinâmicos.
O padrão de design do repositório oferece uma API limpa para administrar atalhos. A vantagem de um repositório é que os detalhes da API são extraídos de maneira uniforme por trás de uma API mínima. Siga as etapas abaixo para implementar o repositório:
- Crie uma classe
ShortcutsRepository
para extrair a APIShortcutManagerCompat
. - Adicione métodos de
ShortcutsRepository
ao localizador de serviços do app. - Registre o serviço
ShortcutRepository
no aplicativo principal.
Criar o repositório
Crie uma classe Kotlin chamada ShortcutsRepository
no pacote com.example.android.architecture.blueprints.todoapp.data.source
. Esse pacote está organizado na pasta app/src/main/java
. Você vai usar essa classe para implementar uma interface que oferece um conjunto mínimo de métodos para nosso caso de uso do codelab.
Figura 2. Janela "Project Files" do Android Studio com o local da classe ShortcutsRepository.
Cole o seguinte código na nova classe:
package com.example.android.architecture.blueprints.todoapp.data.source
import android.content.Context
import android.content.Intent
import androidx.annotation.WorkerThread
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import com.example.android.architecture.blueprints.todoapp.data.Task
import com.example.android.architecture.blueprints.todoapp.tasks.TasksActivity
private const val GET_THING_KEY = "q"
/**
* ShortcutsRepository provides an interface for managing dynamic shortcuts.
*/
class ShortcutsRepository(val context: Context) {
private val appContext = context.applicationContext
/**
* Pushes a dynamic shortcut. The task ID is used as the shortcut ID.
* The task's title and description are used as shortcut's short and long labels.
* The resulting shortcut corresponds to the GET_THING capability with task's
* title used as BII's "name" argument.
*
* @param task Task object for which to create a shortcut.
*/
@WorkerThread
fun pushShortcut(task: Task) {
// TODO
}
private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
//...
}
/**
* Updates a dynamic shortcut for the provided task. If the shortcut
* associated with this task doesn't exist, this method throws an error.
* This operation may take a few seconds to complete.
*
* @param tasks list of tasks to update.
*/
@WorkerThread
fun updateShortcuts(tasks: List<Task>) {
//...
}
/**
* Removes shortcuts if IDs are known.
*
* @param ids list of shortcut IDs
*/
@WorkerThread
fun removeShortcutsById(ids: List<String>) {
//...
}
/**
* Removes shortcuts associated with the tasks.
*
* @param tasks list of tasks to remove.
*/
@WorkerThread
fun removeShortcuts(tasks: List<Task>) {
//...
}
}
Em seguida, atualize o método pushShortcut
para chamar a API ShortcutManagerCompat
. Atualize a classe ShortcutsRepository
com o seguinte código:
ShortcutsRepository.kt
/**
* Pushes a dynamic shortcut for the task. The task's ID is used as a shortcut
* ID. The task's title and description are used as shortcut's short and long
* labels. The created shortcut corresponds to GET_THING capability with task's
* title used as BII's "name" argument.
*
* @param task Task object for which to create a shortcut.
*/
@WorkerThread
fun pushShortcut(task: Task) {
ShortcutManagerCompat.pushDynamicShortcut(appContext, createShortcutCompat(task))
}
No exemplo de código anterior, transmitimos appContext
para a API. Essa é uma propriedade de classe com um contexto de aplicativo. É importante usar um contexto de aplicativo (em vez de um contexto de atividade) para evitar vazamentos de memória, já que o contexto pode ser retido por mais tempo que o ciclo de vida da atividade do host.
Além disso, a API exige que um objeto ShortcutInfoCompat
seja transmitido para o objeto da tarefa. No exemplo de código anterior, fazemos isso chamando o método particular createShortcutCompat
, que vamos atualizar para criar e retornar um objeto ShortcutInfoCompat
. Basta usar o seguinte código no stub createShortcutCompat
:
ShortcutsRepository.kt
private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
val intent = Intent(appContext, TasksActivity::class.java)
intent.action = Intent.ACTION_VIEW
// Filtering is set based on currentTitle.
intent.putExtra(GET_THING_KEY, task.title)
// A unique ID is required to avoid overwriting an existing shortcut.
return ShortcutInfoCompat.Builder(appContext, task.id)
.setShortLabel(task.title)
.setLongLabel(task.title)
// Call addCapabilityBinding() to link this shortcut to a BII. Enables user to invoke a shortcut using its title in Assistant.
.addCapabilityBinding(
"actions.intent.GET_THING", "thing.name", listOf(task.title))
.setIntent(intent)
.setLongLived(false)
.build()
}
Os stubs de função restantes nessa classe cuidam da atualização e da exclusão de atalhos dinâmicos. Para ativar essas funções, atualize com o seguinte código:
ShortcutsRepository.kt
/**
* Updates a Dynamic Shortcut for the task. If the shortcut associated with this task
* doesn't exist, throws an error. This operation may take a few seconds to complete.
*
* @param tasks list of tasks to update.
*/
@WorkerThread
fun updateShortcuts(tasks: List<Task>) {
val scs = tasks.map { createShortcutCompat(it) }
ShortcutManagerCompat.updateShortcuts(appContext, scs)
}
/**
* Removes shortcuts if IDs are known.
* @param ids list of shortcut IDs
*/
@WorkerThread
fun removeShortcutsById(ids: List<String>) {
ShortcutManagerCompat.removeDynamicShortcuts(appContext, ids)
}
/**
* Removes shortcuts associated with the tasks.
*
* @param tasks list of tasks to remove.
*/
@WorkerThread
fun removeShortcuts(tasks: List<Task>) {
ShortcutManagerCompat.removeDynamicShortcuts (appContext,
tasks.map { it.id })
}
Adicionar uma classe ao localizador de serviços
Com a classe ShortcutsRepository
criada, a próxima etapa é disponibilizar objetos instanciados dessa classe para o restante do app. Esse aplicativo gerencia as dependências de classe implementando o padrão do localizador de serviços. Abra a classe do localizador usando o navegador de classes no Android Studio: Navigate > Class e digite "ServiceLocator". Clique no arquivo Kotlin para abrir no seu ambiente de desenvolvimento integrado.
Na parte de cima do ServiceLocator.kt
, cole o seguinte código para importar os pacotes ShortcutsRepository
e SuppressLint
:
ServiceLocator.kt
package com.example.android.architecture.blueprints.todoapp
// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
import android.annotation.SuppressLint
Para adicionar os membros e métodos do serviço ShortcutRepository
, cole o seguinte código no corpo de ServiceLocator.kt
:
ServiceLocator.kt
object ServiceLocator {
// ...
// Only the code immediately below this comment needs to be copied and pasted
// into the body of ServiceLocator.kt:
@SuppressLint("StaticFieldLeak")
@Volatile
var shortcutsRepository: ShortcutsRepository? = null
private fun createShortcutsRepository(context: Context): ShortcutsRepository {
val newRepo = ShortcutsRepository(context.applicationContext)
shortcutsRepository = newRepo
return newRepo
}
fun provideShortcutsRepository(context: Context): ShortcutsRepository {
synchronized(this) {
return shortcutsRepository ?: shortcutsRepository ?: createShortcutsRepository(context)
}
}
}
Registrar o serviço de atalho
A etapa final é registrar o novo serviço ShortcutsRepository
no aplicativo. No Android Studio, abra TodoApplication.kt
e copie o código abaixo na parte de cima do arquivo:
TodoApplication.kt
package com.example.android.architecture.blueprints.todoapp
/// ... Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Em seguida, registre o serviço adicionando o seguinte código ao corpo da classe:
TodoApplication.kt
//...
class TodoApplication : Application() {
//...
val shortcutsRepository: ShortcutsRepository
get() = ServiceLocator.provideShortcutsRepository(this)
//...
}
Compile o app e verifique se ele continua em execução.
5. Enviar um novo atalho
Depois de criar o serviço de atalho, você poderá começar a enviar atalhos. Como os usuários geram conteúdo (itens de tarefa) nesse app e esperam retornar depois, permitimos o acesso por comandos de voz ao conteúdo enviando um atalho dinâmico vinculado à BII GET_THING
sempre que alguém cria uma tarefa. Isso permite que o Google Assistente encaminhe os usuários ao item de tarefa quando acionarem a BII. Basta pedir algo como Ok Google, abra minha lista de compras no AppDeExemplo.
Para ativar essa funcionalidade no app de exemplo:
- Importe o serviço
ShortcutsRepository
para a classeAddEditTaskViewModel
, responsável por gerenciar objetos da lista de tarefas. - Envie um atalho dinâmico quando o usuário criar uma tarefa.
Importar ShortcutsRepository
Primeiro, temos que disponibilizar o serviço ShortcutsRepository
para a classe AddEditTaskViewModel
. Basta importar o serviço para ViewModelFactory
, a classe de fábrica que o app usa para instanciar objetos ViewModel, incluindo AddEditTaskViewModel
.
No Android Studio, acesse Navigate > Class e digite "ViewModelFactory" para abrir o navegador de classes. Clique no arquivo Kotlin para abrir no seu ambiente de desenvolvimento integrado.
Na parte de cima do ViewModelFactory.kt
, cole o seguinte código para importar os pacotes ShortcutsRepository
e SuppressLint
:
ViewModelFactory.kt
package com.example.android.architecture.blueprints.todoapp
// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Em seguida, substitua o corpo de ViewModelFactory
pelo seguinte código:
ViewModelFactory.kt
/**
* Factory for all ViewModels.
*/
@Suppress("UNCHECKED_CAST")
class ViewModelFactory constructor(
private val tasksRepository: TasksRepository,
private val shortcutsRepository: ShortcutsRepository,
owner: SavedStateRegistryOwner,
defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
override fun <T : ViewModel> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
) = with(modelClass) {
when {
isAssignableFrom(StatisticsViewModel::class.java) ->
StatisticsViewModel(tasksRepository)
isAssignableFrom(TaskDetailViewModel::class.java) ->
TaskDetailViewModel(tasksRepository)
isAssignableFrom(AddEditTaskViewModel::class.java) ->
AddEditTaskViewModel(tasksRepository, shortcutsRepository)
isAssignableFrom(TasksViewModel::class.java) ->
TasksViewModel(tasksRepository, handle)
else ->
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
}
} as T
}
Termine de fazer as mudanças em ViewModelFactory
acessando uma camada superior e transmita ShortcutsRepository
ao construtor de fábrica. No Android Studio, acesse Navigate > File e digite "FragmentExt.kt" para abrir o navegador de arquivos. Clique no arquivo Kotlin localizado no pacote util para abrir no ambiente de desenvolvimento integrado.
Substitua o corpo de FragmentExt.kt
pelo seguinte código:
fun Fragment.getViewModelFactory(): ViewModelFactory {
val taskRepository = (requireContext().applicationContext as TodoApplication).taskRepository
val shortcutsRepository = (requireContext().applicationContext as TodoApplication).shortcutsRepository
return ViewModelFactory(taskRepository, shortcutsRepository, this)
}
Enviar um atalho
Com a classe de extração ShortcutsRepository
disponível para as classes ViewModel
do app de exemplo, você atualiza AddEditTaskViewModel
(a classe ViewModel
responsável por criar notas) para enviar um atalho dinâmico sempre que alguém criar uma observação.
No Android Studio, abra o navegador de classes e digite "AddEditTaskViewModel". Clique no arquivo Kotlin para abrir no seu ambiente de desenvolvimento integrado.
Primeiro, adicione o pacote ShortcutsRepository
a essa classe com a seguinte instrução de importação:
package com.example.android.architecture.blueprints.todoapp.addedittask
//Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Depois, adicione a propriedade da classe shortcutsRepository
atualizando o construtor de classe com o seguinte código:
AddEditTaskViewModel.kt
//...
/**
* ViewModel for the Add/Edit screen.
*/
class AddEditTaskViewModel(
private val tasksRepository: TasksRepository,
private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {
//...
Com a classe ShortcutsRepository
adicionada, crie outra função (pushShortcut()
) para chamar essa classe. Cole a seguinte função particular no corpo de AddEditTaskViewModel
:
AddEditTaskViewModel.kt
//...
private fun pushShortcut(newTask: Task) = viewModelScope.launch {
shortcutsRepository.pushShortcut(newTask)
}
Envie um novo atalho dinâmico sempre que uma tarefa for criada. Substitua o conteúdo da função saveTask()
pelo seguinte código:
AddEditTaskViewModel.kt
fun saveTask() {
val currentTitle = title.value
val currentDescription = description.value
if (currentTitle == null || currentDescription == null) {
_snackbarText.value = Event(R.string.empty_task_message)
return
}
if (Task(currentTitle, currentDescription).isEmpty) {
_snackbarText.value = Event(R.string.empty_task_message)
return
}
val currentTaskId = taskId
if (isNewTask || currentTaskId == null) {
val task = Task(currentTitle, currentDescription)
createTask(task)
pushShortcut(task)
} else {
val task = Task(currentTitle, currentDescription, taskCompleted, currentTaskId)
updateTask(task)
}
}
Testar o código
Chegou a hora de testar nosso código. Nesta etapa, você envia um atalho dinâmico ativado por comando de voz e faz a inspeção dele usando o app Google Assistente.
Criar uma prévia
Crie uma prévia usando o plug-in do Google Assistente e faça com que seus atalhos dinâmicos apareçam no Assistente no dispositivo de teste.
Instalar o plug-in de teste
Siga estas etapas para instalar o plug-in do Google Assistente no Android Studio:
- Acesse **File > Settings (Android Studio > Preferences no MacOS).
- Na seção Plugins, acesse Marketplace e pesquise "Google Assistant".
- Se você não encontrar o plug-in no Marketplace, faça o download dele e siga as instruções em Instalar o plug-in do disco (links em inglês).
- Instale a ferramenta e reinicie o Android Studio.
Criar a prévia
Para criar uma prévia, siga estas etapas no Android Studio:
- Clique em Tools > Google Assistant > App Actions Test Tool.
- Na caixa App name, insira o nome, como "Lista de tarefas".
- Clique em Create preview. Confira e aceite as políticas e os Termos de Serviço das Ações no app, se for o caso.
Figura 3. Painel de criação da prévia na App Actions Test Tool.
Durante os testes, os atalhos dinâmicos enviados ao Google Assistente vão aparecer nele, organizados de acordo com o nome do app escolhido para a prévia.
Enviar e inspecionar um atalho
Reinicie o app de exemplo no dispositivo de teste e siga estas etapas:
- Crie uma tarefa com o título "Iniciar o codelab".
- Abra o app Google Assistente e fale ou digite: "Meus atalhos".
- Toque na guia Explore. Você vai encontrar o atalho de exemplo.
- Invoque o atalho tocando nele. O app vai abrir com o nome do atalho pré-preenchido na caixa de filtro, facilitando a localização do item de tarefa pedido.
6. (Opcional) Atualizar e excluir um atalho
Além de enviar novos atalhos dinâmicos no ambiente de execução, o app pode atualizá-los de acordo com o conteúdo e as preferências do usuário. É recomendável atualizar os atalhos sempre que alguém modificar o item de destino (por exemplo, renomear uma tarefa no nosso app de exemplo). Além disso, sempre exclua um atalho correspondente quando o recurso de destino for removido para não mostrar atalhos corrompidos ao usuário.
Atualizar um atalho
Modifique AddEditTaskViewModel
para atualizar um atalho dinâmico sempre que alguém mudar os detalhes de um item de tarefa. Primeiro, atualize o corpo da classe com o código abaixo para adicionar uma função de atualização que use nossa classe de repositório:
AddEditTaskViewModel.kt
private fun updateShortcut(newTask: Task) = viewModelScope.launch {
shortcutsRepository.updateShortcuts(listOf(newTask))
}
Depois, modifique a função saveTask()
para chamar nosso novo método sempre que uma tarefa for atualizada.
AddEditTaskViewModel.kt
// Called when clicking on fab.
fun saveTask() {
// ...
// Note: the shortcuts are created/updated in a worker thread.
if (isNewTask || currentTaskId == null) {
//...
} else {
//...
updateShortcut(task)
}
}
Reinicie o app e siga as etapas abaixo para testar o código:
- Renomeie o título do item de tarefa como "Concluir o codelab".
- Abra o Google Assistente dizendo "Ok Google, meus atalhos".
- Toque na guia Explore. Você vai notar um pequeno rótulo atualizado para o atalho de teste.
Remover um atalho
Os atalhos dos apps de exemplo precisam ser removidos sempre que alguém exclui uma tarefa. No aplicativo de exemplo, a lógica de exclusão de tarefas fica na classe TaskDetailViewModel
. Antes de atualizar essa classe, é necessário modificar ViewModelFactory
de novo para transmitir shortcutsRepository
a TaskDetailViewModel
.
Abra ViewModelFactory
e substitua o conteúdo do método construtor pelo seguinte código:
//...
class ViewModelFactory constructor(
private val tasksRepository: TasksRepository,
private val shortcutsRepository: ShortcutsRepository,
owner: SavedStateRegistryOwner,
defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
override fun <T : ViewModel> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
) = with(modelClass) {
when {
isAssignableFrom(StatisticsViewModel::class.java) ->
StatisticsViewModel(tasksRepository)
isAssignableFrom(TaskDetailViewModel::class.java) ->
TaskDetailViewModel(tasksRepository, shortcutsRepository)
isAssignableFrom(AddEditTaskViewModel::class.java) ->
AddEditTaskViewModel(tasksRepository, shortcutsRepository)
isAssignableFrom(TasksViewModel::class.java) ->
TasksViewModel(tasksRepository, handle)
else ->
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
}
} as T
}
Depois, abra TaskDetailViewModel
. Importe o módulo ShortcutsRepository
e declare uma variável de instância usando o seguinte código:
TaskDetailViewModel.kt
package com.example.android.architecture.blueprints.todoapp.taskdetail
...
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
/**
* ViewModel for the Details screen.
*/
class TaskDetailViewModel(
//...
private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {
...
}
Por último, modifique a função deleteTask()
para chamar shortcutsRepository
e remover um atalho com base no ID sempre que uma tarefa com um taskId
correspondente for excluída:
TaskDetailViewModel.kt
fun deleteTask() = viewModelScope.launch {
_taskId.value?.let {
//...
shortcutsRepository.removeShortcutsById(listOf(it))
}
}
Para testar o código, reinicie o app e siga estas etapas:
- Exclua a tarefa de teste.
- Renomeie o título do item de tarefa como "Concluir o codelab".
- Abra o Google Assistente dizendo "Ok Google, meus atalhos".
- Toque na guia Explore. Confirme se o atalho de teste desapareceu.
7. Próximas etapas
Parabéns! Agora os usuários do nosso app de exemplo conseguem retornar às observações que criaram com o Assistente. Basta dizer: Ok Google, abra minha lista de compras no AppDeExemplo. Os atalhos incentivam mais interações dos usuários, facilitando a repetição das ações mais comuns no seu app.
O que aprendemos
Neste codelab, você aprendeu a:
- Identificar casos de uso para enviar atalhos dinâmicos em um app.
- Reduzir a complexidade do código usando padrões de design para repositórios, injeções de dependências e localizadores de serviços.
- Enviar atalhos dinâmicos ativados por comandos de voz para conteúdo gerado pelo usuário no app.
- Atualizar e remover atalhos.
O que vem a seguir
Você pode melhorar ainda mais o app de lista de tarefas. Para fazer referência ao projeto finalizado, consulte o repositório da ramificação -codelab-complete no GitHub (link em inglês).
Confira algumas sugestões para integrar esse aplicativo usando as Ações no app:
- Consulte o exemplo de listas de tarefas com o Google Analytics para Firebase para aprender a monitorar a performance das suas Ações no app.
- Acesse a referência de intents integradas das Ações no app para descobrir mais formas de integrar seus apps ao Google Assistente.
Para continuar sua jornada na plataforma Actions on Google, confira estes recursos:
- actions.google.com/assistant: site da documentação oficial da plataforma Actions on Google
- Índice de exemplos de Ações no app: códigos e aplicativos de exemplo para conhecer os capabilities das Ações no app
- Repositório do GitHub da plataforma Actions on Google (link em inglês): exemplo de código e bibliotecas
- r/GoogleAssistantDev: comunidade oficial do Reddit em inglês para desenvolvedores que trabalham com o Google Assistente
Siga nosso perfil @ActionsOnGoogle no Twitter, fique por dentro das novidades e envie um tweet com #appactions para mostrar o que você criou.
Pesquisa de feedback
Para terminar, responda a esta pesquisa e dê seu feedback sobre o que achou do codelab.