Machine Learning — api.ai + Android

Embora ter o nosso agente no Facebook e a enviar imagens pode ser bastante útil para lojas e empresas/organizações, talvez você queria desenvolver um assistente pessoal: a sua própria Siri ou Cortana.

Lembrar que este é o 5º artigo da série Machine Learning. Se você não acompanhou esta série desde o ínicio, aí tem uma oportunidade:

Como sempre, para começarmos uma aplicação Android, temos de criar o projecto no Android Studio. Não vou detalhar este passo assumindo que você já sabe fazer isso (caso não, leia este artigo).

Adicionar o api.ai ao projecto Android

Adicionar as bibliotecas

Depois de criar o nosso projecto, temos que adicionar as bibliotecas do api.ai ao projecto Android. E fazemos isso adicionando dependencias ao gradle, basta colocar as seguintes linhas no ficheiro build.gradle (app):

compile 'ai.api:libai:1.3.5'
compile 'ai.api:sdk:2.0.2@aar'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.google.code.gson:gson:2.3'
compile 'commons-io:commons-io:2.4'

Adicionar permissões ao Manifest

No seu ficheiro AndroidManifest.xml que fica na pasta app/src/main, adicione as seguintes permissões (antes da tag <application>):

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Criar a Activity

Desenho da interface do utilizador (xml)

Vamos criar uma interface simples só para que você tenha uma noção de como funciona esta integração. A nossa Activity terá apenas uma TextView e um Button:

Conexão com o nosso agente

Vamos começar por permitir que a nossa aplicação receba as respostas do agente. Para isso, temos de ter uma classe que implementa a interface AIListener. Podemos implementar esta interface na nossa Activity:

public class MainActivity extends AppCompatActivity implements AIListener {

Esta interface tem 6 métodos que você deve obrigatoriamente colocar na Activity:

void onResult(AIResponse result){} // é aqui onde você processa o resultado da requisição (a resposta)
void onError(AIError error){} // chamado caso ocorra um erro
void onAudioLevel(float level){} // indica o nível do som quando o usuário está a falar
void onListeningStarted() // quando o microfone é activado
void onListeningCanceled(){} // quando o microfone é cancelado (porque o usuário cancelou ou ocorreu um erro)
void onListeningFinished(){} // quando o microfone é desactivado (porque o usuário terminou de falar)

Em seguida, vamos criar duas variáveis e inicializá-las:

public class MainActivity extends AppCompatActivity implements AIListener{
private AIConfiguration config;
private AIService service;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

config = new AIConfiguration("CLIENT_ACCESS_TOKEN",
AIConfiguration.SupportedLanguages.Portuguese,//Altere esta linha de acordo com o idioma que voce escolheu na consola
AIConfiguration.RecognitionEngine.System);
service = AIService.getService(this, config);
service.setListener(this);
}

}

Substitua CLIENT_ACCESS_TOKEN pelo access token do seu agente. Para obter este token, basta ir às definições do agente na consola do api.ai.

Enviar requisições

Para a nossa aplicação poder enviar requisições por voz, basta adicionarmos um onClickListener ao nosso botão e chamar o metodo startListening():

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
service.startListening();
}
});

Mostrar a resposta

E depois recebemos respostas e/ou erros da requisição nos métodos onResult e onError:

@Override
public void onResult(AIResponse response) {
Result result = response.getResult();

// Obter os parametros caso existam
String parameterString = "";
if (result.getParameters() != null && !result.getParameters().isEmpty()) {
for (final Map.Entry<String, JsonElement> entry : result.getParameters().entrySet()) {
parameterString += "(" + entry.getKey() + ", " + entry.getValue() + ") ";
}
}

// Show results in TextView.
textView.setText("Query:" + result.getResolvedQuery() + //A frase que o utilizador usou
"\nSpeech: " + result.getFulfillment().getSpeech() + //A resposta
"\nParameters: " + parameterString); //Os parametros
}

@Override
public void onError(AIError error) {
textView.setText(error.toString());
}

A Activity final fica assim:

E agora é so executar a aplicação no seu telemóvel ou emulador e você terá uma tela semelhante a esta:

E pronto. Criar uma versão simplificada do Google Assistant é tão simples quanto isto. Você pode obter o projecto inteiro no GitHub.

No próximo artigo veremos como permitir que a nossa aplicação realize acções de acordo com o Intent utilizado:


Se você tem alguma dúvida ou sugestão, não hesite em me contactar pelo email rosariofernandes51@gmail.com ou pelo Telegram. Ficarei feliz por conversar com você. :)