Tutorial app de mensagens para Android com backend em Node.js

Ok, já temos Whatsapp, Telegram, Slack e outras incríveis plataformas de mensagens no mercado, mas não é por isso que deixa de ser valioso saber desenvolver uma aplicação que permite a troca de mensagens entre diferentes usuários.

Diversos são os contextos em que você pode ganhar dinheiro com apps de mensagens, como criando chatbots, usando a parte de mensageria como backend de outro tipo de operação, criando mensageiros para atender demandas específicas de empresas e por aí vai.

Sendo assim, o intuito deste post é permitir que você seja capaz de criar uma aplicação cliente de mensagens para a plataforma Android. O message-server obviamente não estará no app Android, mas sim em uma hospedagem ou servidor na nuvem, que será o ponto central para todos os clientes se conectarem.

Para o servidor de mensagens (backend), usaremos Node.js com Socket.io. As mensagens não serão persistidas, mas poderíamos fazê-lo com MongoDB, se assim quiséssemos. Essas tecnologias casam muito bem com conceitos como real-time, comunicação de rede não bloqueante e programação assíncrona baseada em eventos (falei muito disso neste post de Node). Não é ao acaso que foram escolhidas para servir de backend para este tutorial e no vídeo abaixo explico um pouco disso e do porque ainda programo usando o SDK nativo do Android:

Veremos neste tutorial:

  1. Preparando o back-end
  2. Criando o app
  3. Programando a troca de mensagens
  4. Indo além

Vamos lá!

#1 – Preparando o back-end

O seu app irá conversar com um back-end que eu ensinei como criar em um tutorial recente sobre Node.js com Socket.io.

Ao terminar o referido tutorial, você terá uma aplicação web de chat com servidor socket.io e é imprescindível que faça o mesmo antes de começar esse aqui, até para entender como funciona o Socket.io, o seu modelo de eventos, a troca de mensagens, etc.

Se você preferir, no referido post há um formulário para baixar o zip com o projeto pronto. Pode partir disso também, mas certifique-se de instalar as dependências com ‘npm install’, rode o projeto localmente e teste para ver se está tudo funcionando.

Opcionalmente, existem diversas coisas que não foram implementadas no referido tutorial mas que são citadas na última seção, dentre elas persistência de dados e autenticação, dois itens muito importantes para um app de mensagens que posso explorar em continuações deste tutorial.

Em suma, não há muito o que fazer aqui, pois tudo já foi feito no outro post.

Vamos em frente!

#2 – Criando o app

Se esse é o seu primeiro projeto com Android, recomendo começar por este post aqui, muito mais didático.

Crie um novo projeto no Android Studio com o nome de ChatApp e na Activity inicial use uma Empty Activity e deixe com as configurações sugeridas (nome de MainActivity, etc). Em chats mais avançados como clones do Whatsapp, poderíamos usar o template com abas para ter a listagem de contatos em uma, a conversa em outra, etc.

Nossa interface será bem simples: uma lista de mensagens, um campo para escrever uma nova mensagem e um botão de enviar, tal qual o layout abaixo, que pode ser feito de diversas maneiras por ser bem simples, sendo que as que recomendo são com Constraint Layout ou com Relative Layout.

Chat App
Chat App

Usei nesta interface uma ListView, que é um componente rápido e prático de implementar listas simples. Existe outro componente chamado RecyclerView, muito mais poderoso e com mais opções, que eu recomendo dar uma olhada se esse projeto for tomar grandes proporções ou virar importante para você. Para conhecer o RecyclerView. sugiro este outro tutorial aqui.

O código completo do layout pode ser visto abaixo, com atenção aos ids dos componentes e ao onClick do Button, o restante você pode mudar à vontade:

Para que nossa ListView liste as mensagens que adicionaremos mais tarde e para que a caixa de texto possa ser lido depois, adicione as seguintes modificações no método onCreate da sua MainActivity.java:

Neste código eu carrego os componentes de interface em variáveis locais, para que eu possa manipulá-los mais tarde. Também crio um adapter que terá os dados a serem listados na minha ListView. Mais tarde, quando eu quiser atualizar ela, basta adicionar novos elementos no adapter.

Para que o click do botão seja manipulado eu adicionei o nome de um método à propriedade onClick do Button: btnEnviarOnClick. Esse método ainda não existe, vamos criá-lo em nossa MainActivity.java, como abaixo:

Neste código Java eu apenas estou lançando a mensagem digitada diretamente  na ListView (através do adapter), como se fosse uma conversa consigo mesmo. Mais tarde mudaremos este código para enviar ao servidor de mensagens.

Você até pode rodar este app do jeito que está, mas não vai ver nada de incrível, apenas um botão que exibe o texto digitado na listagem.

Chat Fake
Chat Fake

Com isso, o arcabouço do nosso app está pronto para receber a lógica de comunicação com o servidor de mensagens.

Curso Node.js e MongoDB
Curso Node.js e MongoDB

#3 – Programando a troca de mensagens

Para usar o cliente do Socket.io em apps Android, devemos adicionar manualmente uma dependência no build.gradle, dentro da coleção “dependencies”.

Isso exigirá que o Gradle seja sincronizado com o repositório e ele vai baixar essa biblioteca cliente que o pessoal do Socket.io deixou pronta para uso com Android.

Como o Socket.io irá se conectar à Internet, precisamos dessa permissão explícita em nosso AndroidManifest.xml:

E para versões de Android 6+, precisaremos também solicitar essa permissão no momento que precisarmos do recurso, para garantir que a teremos. Como ao abrir o aplicativo já estaremos esperando pelas mensagens do servidor, precisamos dessa permissão logo no início do ciclo de vida Activity, no onCreate.

Antes disso, vamos criar dois novos e métodos e alterar o onClick do botão e o onCreate da Activity como segue:

O primeiro método vamos modificar ele para fazer o setup do cliente do Socket.io e ficar aguardando as mensagens. Já o segundo método, vamos alterar para enviar as mensagens para o server do Socket.io. Ambos métodos dependem que exista uma conexão (e permissão para usar) com a Internet.

Primeiro, vamos declarar uma variável cliente do Socket.io no topo da nossa Activity, junto às demais variáveis, como segue:

Quando você declarar esta variável terá de importar a dependência correta. O Android Studio dá 3 opções, a correta é a do meio, conforme mostra a foto abaixo:

Import correto
Import correto

Agora, dentro do método waitMessage, vamos adicionar o seguinte código de inicialização do Socket.io:

O endereço 10.0.2.2 é o localhost da máquina host da VM do Android e a porta 3000 é a default do Node.js. Caso seu message-server esteja hospedado em algum lugar (recomendo subir para a Umbler), coloque aqui a URL ou IP correspondente (de preferência a URLs ao invés de IPs).

Outros pontos importantes deste código incluem o runOnUiThread que delega à thread de UI a atualização da interface, para evitar o erro “CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.” e o uso de smoothScrollToPosition para jogar o scroll sempre para o final da ListView possibilitando ao usuário enxergar as novas mensagens mais facilmente.

Enquanto esse código aí faz a conexão do Socket, precisamos de um código para encerrar essa conexão, que deve ir no onDestroy da Activity, um método que devemos incluir como abaixo:

Agora vem a parte chata de pedir permissão, altera a chamada ao waitMessage no onCreate para que fique dessa maneira, solicitando a permissão de internet:

Primeiro, note que declarei uma constante lá no início do código, essa constante é o código da operação que quero realizar. Quando vou configurar o cliente do Socket.io, eu verifico se tenho a permissão de Internet concedida. Caso já tenha, cai no else e configura. Caso contrário, eu solicito ao sistema que peça essa permissão ao usuário, passando o código da tarefa que quero realizar após a permissão ser concedida.

Mas como saberei se o usuário me deu a permissão?

Aí entra o trecho de código abaixo, que trata a resposta a pedidos de permissão de maneira assíncrona:

Ou seja, caso a permissão tenha sido concedida e o código da ação a ser executada for igual a READ_SOCKET, eu mando executar o waitMessage. Caso contrário mando um aviso default pois o app não irá funcionar.

Isso tudo já é o suficiente para que recebamos mensagens, então abra a aplicação web de chat que criamos no tutorial anterior com “npm start”, abra no navegador na URL localhost:3000/chat e abra o seu app Android no simulador também. Possivelmente na primeira execução ele vai pedir a permissão de Internet e você deve fornecer. Quando você digitar mensagens na aplicação web, elas aparecerão no app automaticamente, como mostra a imagem abaixo:

Recebendo Mensagens
Recebendo Mensagens

Agora, para finalizar, vamos fazer com que as mensagens escritas no app sejam enviadas para o servidor, a fim de atualizar também a aplicação web automaticamente. Atualize os métodos sendMessage e onRequestPermissionsResult como abaixo:

Note que defini uma nova constante com o código 2, para que seja possível distinguir as solicitações de permissão, caso não sejam feitas na ordem normal (leitura primeiro, escrita depois) ou seja revogada nesse meio tempo. Essa constante é usada em um novo ‘case’ no onRequestPermissionsResult, enquanto que a ação de enviar mensagens ao servidor é ridiculamente simples, um mero socket.emit passando o nome do evento (aqui estou usando o mesmo nome de evento do tutorial anterior) já resolve.

Como o meu servidor está fazendo broadcast de tudo que recebe, automaticamente a mensagem do app ecoará de volta atualizando a lista, sem que eu tenha de me preocupar com isso.

O resultado agora é um app de chat se comunicando com um webapp de chat através de Socket.io, como mostra na imagem abaixo, em uma comunicação bi-lateral:

Enviando Mensagens
Enviando Mensagens

E inclusive você pode abrir diversos clientes web e diversos clientes Android que todo mundo consegue conversar com todo mundo sem problema algum, como mostra a imagem abaixo!

Todo mundo conversando
Todo mundo conversando

#4 – Indo além

Note que criar este tipo de aplicação antes de termos tecnologias modernas e consolidadas como Socket.io era realmente difícil. Hoje é possível criar um servidor de chat com 12 linhas Node.js no server (embora o meu esteja maior) e uma Activity no client, como fizemos aqui. E esse conhecimento pode ser extendido para criação de jogos por exemplo, pois o modelo de eventos do Socket.io permite que você comunique o que quiser e no formato que quiser através dele, coisa que aqui apenas mandei mensagens de texto simples.

Itens que você pode considerar para ampliar este projeto e torná-lo uma aplicação de mensageria mais profissional:

  • hospedagem do server em um provedor de hospedagem ou servidor na nuvem;
  • autenticação das requisições;
  • uso de HTTPS para comunicação segura;
  • persistência das mensagens no server, sugiro MongoDB, e no client com SQLite;
  • mensagens privadas;
  • suporte a nicknames;
  • busca de mensagens;
  • push notifications quando novas mensagens chegarem (hoje elas chegam mesmo com o app em background, só não avisam o usuário);
  • aviso textual quando o usuário estiver digitando uma mensagem;
  • sinalização de quem está online no chat;

E muito mais!

Espero que tenham gostado deste tutorial, pois foi realmente interessante e divertido fazê-lo!

Eeste post é coberto pelos slides abaixo, frutos de um workshop meu.

Curtiu o post? Então dá uma olhada no meu livro de Android clicando no banner abaixo pra aprender a criar outros tantos apps incríveis!

Criando apps para empresas com Android

O que achou desse artigo?
[Total: 5 Média: 4.8]

Publicado por

Luiz Duarte

Pós-graduado em computação, professor, empreendedor, autor, Agile Coach e programador nas horas vagas.