Buscar

Ciclo de Vida da Activity no Android

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 46 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 46 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 46 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 1/46
 
 
 
 
 
 
 
 
 
PROGRAMAÇÃO IV
AULA 5
 
 
 
 
 
 
 
 
 
 
 
 
Prof. Ricardo Rodrigues Lecheta
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 2/46
CONVERSA INICIAL
Olá, seja bem-vindo a mais uma aula!
Nós já aprendemos como criar layouts em XML e como tratar os eventos nas telas. A estrutura
básica de um aplicativo já estudamos, e nesta aula vamos aprender mais detalhes sobre a classe
Activity.
Nos aplicativos Android, tudo gira em torno de uma activity. Ela representa uma tela do
aplicativo, sendo responsável pelo layout e lógica. Nesta aula, vamos estudar o ciclo de vida de uma
activity, que é um dos assuntos mais importantes para que você seja um desenvolvedor Android de
sucesso. Também vamos estudar como passar parâmetros de uma tela para outra, e detalhes sobre a
classe Intent, que é uma das mais importantes no Android, sendo usada desde para abrir uma tela do
aplicativo até para chamar outros aplicativos como o browser, Google Maps, câmera etc.
TEMA 1 – CICLO DE VIDA DA ACTIVITY
Chegou o momento de entender um dos assuntos mais importantes sobre uma activity, que é o
seu ciclo de vida. Falando com um português bem claro, o ciclo de vida consiste em um conjunto de
métodos da classe Activity que é chamado em determinados momentos e representam o estado
atual da activity, por exemplo, se a tela está visível ou parada em segundo plano (background).
Um dos métodos do ciclo de vida nós já estudamos, que é o onCreate(bundle), chamado uma
única vez ao criar a activity e responsável por fazer a inicialização do layout e algumas configurações.
Outro método é o onDestroy(), que é chamado sempre que a tela é fechada, algo que acontece
quando o usuário clica no botão voltar ou se o método finish() é chamado no código. Em ambos os
casos, a activity é eliminada de memória, e nesse momento, podemos limpar os recursos e objetos
utilizados, caso seja necessário.
Uma forma simples de entender o ciclo de vida é com um exemplo prático de uso de GPS no
aplicativo. Imagine que o aplicativo precisa obter a localização do usuário sempre que ele entra em
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 3/46
uma determinada tela e depois mostrar um mapa com esta localização. Porém, sabemos que ao
chamar as funções de GPS, existe um aumento significativo no consumo de bateria. Então imagine
que o aplicativo está mostrando um mapa com a localização do usuário, mas depois disso, o usuário
clica no botão Home para voltar à tela inicial para abrir outro aplicativo. Neste momento, a activity do
mapa terá seus métodos onPause() e onStop() chamados, pois a activity foi parada e agora está em
segundo plano (background). Esses métodos onPause() ou onStop() podem ser utilizados para
desligar o monitoramento do GPS e economizar recursos e bateria do celular.
Seguindo o raciocínio, quando o usuário voltar ao aplicativo e mostrar novamente aquele mapa
com a localização, o método onResume() será chamado, o que indica que a tela da activity que
possui o mapa está novamente visível. Neste momento, podemos ligar novamente o GPS.
Acredito que, se você entendeu o que foi explicado acima, já é 90% do caminho andado, mas,
como o tema é um pouco complexo, vamos estudar o diagrama de fluxo oficial do ciclo de vida de
uma activity e cada método em detalhes.
A figura a seguir demonstra o ciclo de vida completo de uma activity, exibindo os possíveis
estados e a chamada de cada método.
Figura 1 – Activity
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 4/46
Depois de ver o diagrama, leia atentamente o significado de cada método do ciclo de vida da
activity.
● onCreate(bundle): o método onCreate(bundle) é chamado uma única vez. O objetivo desse
método é fazer a inicialização necessária para executar o aplicativo. Nele, deve-se criar uma view e
chamar o método setContentView(view) para configurar o layout da tela. O objeto bundle contém os
parâmetros enviados para a activity e pode ser nulo. Vamos estudar sobre passagem de parâmetros
em outra aula.
● onStart(): o método onStart() é chamado quando a activity está ficando visível ao usuário e já
tem uma view. Pode ser chamado depois dos métodos onCreate() ou onRestart(), dependendo do
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 5/46
estado do aplicativo. Este método raramente é usado.
● onRestart(): o método onRestart() é chamado quando uma activity foi parada
temporariamente e está sendo iniciada outra vez. Esse método raramente é usado.
● onResume(): o método onResume() é chamado quando a activity está no topo da pilha
“activity stack” e, dessa forma, já está executando como a activity principal e interagindo com o
usuário. Podemos dizer que o método onResume() representa o estado de que a activity está
executando. É importante você entender que, quando o método onResume() executar, o usuário já
estará vendo a tela. Por isso, esse método é frequentemente utilizado para disparar threads que
consultam os dados em web services ou banco de dados para atualizar as informações da tela.
● onPause(): sempre que a tela da activity fechar, o método onPause() será chamado. Isso pode
acontecer se o usuário pressionar o botão Home ou o botão voltar do Android. Ou também pode
acontecer se você receber uma ligação telefônica. Nesse momento, o método onPause() é chamado
para salvar o estado do aplicativo, para que posteriormente, quando a activity voltar a executar, tudo
possa ser recuperado, se necessário, no método onResume().
● onStop(): o método onStop() é chamado logo depois do método onPause() e indica que a
activity está sendo encerrada e não está mais visível ao usuário. Depois de parada, a activity pode ser
reiniciada, se necessário. Caso isso ocorra, o método onRestart() é chamado para reiniciar a activity.
Caso a activity fique muito tempo parada em segundo plano e o sistema operacional do Android
precise limpar os recursos para liberar memória, o método onDestroy() pode ser automaticamente
chamado para remover completamente a activity da pilha.
● onDestroy(): o método onDestroy() literalmente encerra a execução de uma activity. Ele pode
ser chamado automaticamente pelo sistema operacional para liberar recursos ou pode ser chamado
pelo aplicativo com o método finish() da classe Activity. Depois do método onDestroy() ter
executado, a activity será removida completamente da pilha e seu processo no sistema operacional
também será completamente encerrado.
TEMA 2 – EXEMPLO PRÁTICO SOBRE O CICLO DE VIDA
Para demonstrar as chamadas dos métodos do ciclo de vida, vamos criar a classe LogActivity,
que sobrescreve os principais métodos do ciclo de vida e escreve um log com a classe LogCat. Esta
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 6/46
activity não precisa de XML, portanto, podemos criá-la como uma classe normal com o wizard > File
> New > Kotlin File/Class, e podemos deixá-la no mesmo pacote onde estão as outras activities.
● LogActivity
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 7/46
Importante: sempre que sobrescrever um método da classe Activity, chame o método da
classe-mãe com o super; caso contrário, uma exceção será lançada em tempo de execução.
No início da classe, foi declarada a propriedade className e foi sobrescrito o método get()
para que ela tenha um retorno, facilitando o seu uso no código. A sintaxe é um pouco chatinha, mas
a única coisa que esse código está fazendo é retornar o nome da classe da activity, sem o pacote.
Saiba mais
Para mais detalhes sobre como criar propriedades em Kotlin, segue o link oficial: <https://ko
tlinlang.org/docs/reference/properties.html>.
Essa classe imprime um log quando os métodos do ciclo de vida são chamados. O log é criado
com a tag android, portanto, é necessário criar um filtro para essa tag na janela do LogCat,conforme
já estudamos. O próximo passo é alterar a classe MainActivity para ser filha de LogActivity, assim, ela
vai herdar todos os métodos que foram customizados na sua classe-mãe.
● MainActivity.kt
Altere as outras activities, também. Vamos apresentar exemplos com a activity de Cadastro:
Ao executar o projeto no emulador, não estamos interessados no layout da activity, então, desta
vez, vamos analisar somente os logs que mostram as chamadas para cada método do ciclo de vida.
Na primeira vez que o aplicativo executar, os seguintes logs serão gerados. Observe que os
métodos onCreate(), onStart() e onResume() são chamados na sequência.
https://kotlinlang.org/docs/reference/properties.html
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 8/46
Agora clique no botão voltar (back) do emulador para sair da activity. Observe que agora os
métodos onPause(), onStop() e onDestroy() foram chamados para encerrar o ciclo de vida da activity.
Nesse caso, como o botão voltar foi pressionado, o sistema operacional sabe que a activity
precisa ser destruída. Por isso, o método onDestroy() foi chamado, eliminando completamente a
activity da memória.
Agora volte à tela inicial do emulador e entre novamente no aplicativo. Isso vai chamar os
métodos onCreate(), onStart() e onResume(). Desta vez, clique no botão Home para voltar à tela
inicial. Observe que, nos logs, os métodos onPause() e onStop() foram chamados, mas não o método
onDestroy().
Isso acontece porque a activity não foi completamente destruída, apenas retirada do topo da
pilha, e agora está parada em segundo plano. O método onSaveInstanceState() é um caso à parte e
vamos estudar depois.
Por último, encontre o ícone do aplicativo na tela inicial e abra o aplicativo novamente. Isso vai
reiniciar a activity, fazendo com que ela volte ao topo da pilha para ser executada em primeiro plano.
Assim, os métodos onRestart(), onStart() e onResume() são chamados.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 9/46
Observe que o método onCreate(bundle) é chamado uma única vez. Se a activity estiver parada
em segundo plano, o método onCreate(bundle) não será chamado novamente. Já o método
onResume() é chamado sempre que a tela fica visível ao usuário.
Perceba que os métodos onPause() e onStop() são sempre chamados ao sair da tela. O método
onResume() é chamado sempre que iniciar ou voltar para o aplicativo.
O método onCreate() é chamado apenas na primeira vez que o aplicativo é criado. Caso a
activity seja totalmente destruída, evento que acontece ao clicar no botão voltar, o método
onDestroy() é chamado para eliminar os recursos e encerrar o ciclo de vida da activity. Outra forma
de destruir a activity é chamar o método finish() programaticamente no código.
Entender o funcionamento do ciclo de vida de uma activity é muito importante para desenvolver
aplicativos no Android. Temos de estar preparados para ações externas que podem ocorrer, tal como
uma ligação telefônica para o usuário. Essa ação faz com que o sistema operacional do Android
interrompa (pause/stop) a activity atual, colocando-a em segundo plano. Isso é feito porque o
aplicativo nativo da ligação é que vai ocupar o topo da pilha de atividades. Numa situação como
essa, quando a ligação terminar, temos de voltar e executar o aplicativo de onde ele parou, sem
perder nenhuma informação.
2.1 CICLO DE VIDA AO GIRAR O CELULAR?
Você se lembra que comentamos que ainda estudaríaos o método
onSaveInstanceState(bundle)? Sabe aquele parâmetro bundle que existe no método
onCreate(bundle)? Você já pensou para que ele serve? Pois muito bem, chegou o momento de
obtermos essas respostas.
Ao girar a tela do celular da vertical para a horizontal, o Android vai destruir a activity atual e
recriá-la logo em seguida. Sim, é isso mesmo. O Android faz isso porque ele precisa recriar todas as
views e aplicar espaçamentos e margens adequadas para a nova orientação (vertical ou horizontal).
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 10/46
Durante esse processo de troca de orientação, o Android vai chamar o método
onSaveInstanceState(bundle) na classe da activity. Esse método recebe um objeto do tipo
android.os.Bundle como argumento que deve ser utilizado para armazenar os dados em uma
estrutura de chave e valor. Para demonstrar esse comportamento, vamos executar o aplicativo
novamente. Ao fazer isso, a MainActivity é criada e inserida no topo da pilha, conforme mostram
estes logs:
Agora, pressione os botões do emulador para girar a tela para a horizontal (na barra lateral que
fica na direita do emulador). Caso o emulador não gire, verifique se a opção auto-rotate está
habilitada, pois nas versões mais novas do Android isso vem desligado por padrão.
Figura 2 – Auto-rotate
Crédito: Khuruzero/Shutterstock.
Os logs a seguir mostram que a activity foi destruída e recriada, mas durante esse processo, o
método onSaveInstanceState(bundle) foi chamado.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 11/46
A ideia é que se o aplicativo salvou valores no Bundle (estrutura de chave e valor) lá no método
onSaveInstanceState(bundle), é possível recuperar esses valores no bundle que vem como
parâmetro no método onCreate(bundle?). É para isso que serve esse bundle no método
onCreate(bundle?). Se for a primeira vez que a activity é executada, o parâmetro bundle sempre
estará nulo, por isso ele contém a sintaxe da interrogação (? – pode ser nulo). Entretanto, no caso da
rotação da tela em que o Android faz esse processo para recriar a activity, o parâmetro bundle pode
estar preenchido com os dados salvos no método onSaveInstanceState(bundle).
Uma vez que já entendemos que o Android precisa matar a tela para recriar o layout na vertical
ou horizontal, quando que na prática precisamos usar esses métodos para manter o estado da tela?
Bom, imagine que seu aplicativo fez uma busca em um web service para mostrar uma lista de
produtos, aliás, vamos estudar listas nas próximas aulas. Caso o usuário gire a tela do celular,
sabemos que a tela será destruída e recriada, e nesse caso, vamos perder a lista. Se não fizermos
nada, o aplicativo vai buscar a lista novamente no web service, porém, para isso, será feita uma nova
requisição na internet, algo que poderia ser evitado. Em vez disso, poderíamos salvar a lista dentro
daquele bundle (HashTable), e depois podemos recuperar essa lista já pronta quando o método
onCreate(bundle) for chamado.
Como ainda não estudamos listas, vamos implementar um exemplo mais simples para que você
consiga visualizar tudo isso funcionando na prática. A ideia é salvar uma variável inteira chamada
count na classe. E a cada vez que a tela for rotacionada, vamos incrementar o valor dessa variável e
salvá-la no bundle. A seguir, podemos ver a alteração de código necessária na MainActivity. Observe
que estão omitidas as demais partes do código para simplificar o exemplo:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 12/46
Ao executar o projeto, a activity será iniciada e os métodos do ciclo de vida serão chamados.
Neste momento, o valor da variável count é 0 (zero).
Ao girar a tela do emulador, a activity será destruída conforme já estudamos, e o método
onSaveInstanceState(bundle) vai incrementar o valor da variável count e salvar o estado. Quando o
método onCreate(bundle) for chamado novamente, a variável count estará lá. Neste exemplo, se
você ficar rotacionando a tela continuamente, a variável count ficará sendo incrementada todas as
vezes.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 13/46
2.2 CICLO DE VIDA AO NAVEGAR ENTRE AS TELAS?
Ao navegar de uma tela para outra chamando método startActivity(intent), como fizemos com
os botões da tela inicial de login, também chamam os métodos do ciclo de vida. Para exercitar mais
uma vez e consolidar os conceitos aprendidos, abra o aplicativo novamentee fique olhando os logs.
Depois, clique em algum dos botões como o de cadastro e veja os logs novamente. Podemos ver que
foram gerados os seguintes logs:
Claramente podemos ver que a MainActivity foi parada (pause/stop) e a CadastroActivity foi
criada e iniciada com as chamadas dos métodos onCreate > onStart > onResume. Então lembre-se,
caso a MainActivty estivesse usando recursos como GPS, Bluetooth ou qualquer outro que não seja
necessário na próxima tela, você deve parar estes recursos neste momento.
Agora na tela de cadastro, clique no botão voltar. Desta vez, veremos os seguintes logs, o que
mostra que a tela de cadastro foi destruída, e a MainActivity foi reiniciada com onRestart > onStart
> onResume. Geralmente, no onResume() é onde colocamos os códigos para reiniciar os recursos
que essa tela precisa, seja ligar GPS, Bluetooth, ou refazer uma busca no web service para preencher
os dados da tela.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 14/46
Com isso, concluímos nossos estudos sobre o ciclo de vida de uma activity, então, vamos agora
falar de Intents.
TEMA 3 – PASSANDO PARÂMETROS AO NAVEGAR ENTRE TELAS
Na primeira tela do aplicativo, aprendemos que, para abrir uma nova activity, podemos usar o
método startActivity(intent):
Para facilitar a leitura do código, vamos declarar uma variável para o objeto Intent que é
passado como parâmetro na chamada do método.
Mas o que é este objeto intent? Explicando de uma maneira simples, a intent é o objeto que
contém a "intenção" de abrir a tela, e nela podemos adicionar parâmetros para a próxima tela. Para
que você entenda bem como isso funciona, vamos mais uma vez fazer um exemplo prático.
Lembra quando fizemos o login? Nossa classe LoginService está assim:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 15/46
Isso significa que ao logar com ricardo/123, um objeto Usuário será criado e o nome será
Ricardo. Crie a combinação que preferir para testar. No próximo exemplo, nosso objetivo será
mostrar o nome do usuário logado na tela da Home, conforme mostra esta figura:
Figura 3 – Nome de usuário
Crédito: Khuruzero/Shutterstock.
A seguir, podemos ver o código que trata a função de login e faz a passagem de parâmetro do
nome do usuário para a próxima tela. As alterações estão destacadas em amarelo. Observe que a
intent possui o método putExtras(bundle) que recebe o objeto Bundle, o qual contém os
parâmetros. Mais uma vez, o objeto bundle é uma HashTable e, portanto, possui a estrutura de chave
e valores.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 16/46
No código, veja que ao criar o objeto Bundle, foi dado o nome de args para a variável:
Isso é um padrão bem comum no desenvolvimento, pois neste caso, o Bundle representa os
argumentos (args) que estamos passando como parâmetro para a próxima activity.
Para finalizar o exemplo, precisamos modificar o layout da HomeActivity para mostrar um texto
no centro da tela, portanto, faça a seguinte alteração no arquivo activity_home.xml:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 17/46
Observe que foi utilizado um LinearLayot com gravity=center para deixar o texto centralizado.
O id do TextView é tNome, isso significa que podemos acessar essa view com essa variável no
código, que é criada automaticamente pelo Kotlin Extensions. O código atualizado da HomeActivity
fica assim:
Destacamos em amarelo o import que deve ser feito do arquivo XML para que o Kotlin
Extensions encontre a variável tNome. Preste atenção e não erre essa linha. Como é uma boa prática
utilizar o mesmo id em diversos arquivos XML, repare que o id tNome também existe no arquivo de
layout XML do cadastro. Um erro comum é importar o arquivo errado, o qual não está sendo
utilizado nesta tela.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 18/46
Esse código é simples e está recuperando a mesma intent que é enviada pela activity. Na
segunda linha, a variável nome é lida dos parâmetros que foram enviados. E na terceira linha, o texto
do TextView é atualizado com o nome enviado como parâmetro. Esperamos que esse exemplo tenha
sido simples de entender. Se você alterar o código da classe LoginService, poderá criar várias
combinações de login e senha para testar e brincar.
3.1 PASSANDO UM OBJETO COMO PARÂMETRO
No exemplo anterior, vimos como passar parâmetros utilizando o objeto bundle, mas o código
que fizemos tem um problema, pois passamos a variável "nome" isoladamente, e se for necessário
passar outros dados do usuário, como o email, teremos que criar outra linha para este parâmetro, por
exemplo:
Isso não é uma boa prática em termos de manutenção de código, pois se tivermos muitos
parâmetros, teremos que adicionar várias linhas e isso pode até resultar em algum erro de lógica.
Então, como podemos resolver esse problema? É muito simples, o correto é passar o objeto Usuário
completo como parâmetro. Para fazer isso, vamos utilizar o método putSerializable(s) conforme
mostrado a seguir:
Ao fazer essa alteração, o código não vai compilar, portanto, mantenha a calma. Provavelmente,
aquela variável 'user' ficou vermelha, e se você passar o mouse em cima dela, o Android Studio vai
dizer que ela não é do tipo Serializable.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 19/46
Este Serializable é uma interface de marcação do Java que indica que um objeto pode ser
serializado, ou seja, pode ser convertido de objeto para bytes e vice-versa. A boa notícia é que essa
interface não possui nenhum método para implementar, e justamente por isso falamos que ela é uma
interface de marcação, pois basta implementá-la para “marcar” esse objeto como Serializable e
pronto, o resto o Java faz sozinho. Talvez você possa achar estranho falar de Java, mas o fato é que o
Kotlin consegue chamar todos as classes e códigos do Java, e vale lembrar também que todo o SDK
do Android é feito em Java internamente. Essa interoperabilidade entre o Kotlin e o Java é um dos
grandes pontos fortes do Kotlin, pois ele traz mais produtividade no desenvolvimento, e ainda
consegue chamar classes do Java.
Note que, como estamos usando uma Data Class, entre parênteses está o construtor do objeto e
lá ficam todos os atributos da classe. Depois dos parênteses, foi colocada a sintaxe para implementar
uma interface.
Com a classe Usuário pronta, o código agora está compilando normalmente e já podemos
alterar a classe HomeActivity para ler o objeto enviado como parâmetro:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 20/46
Tenha atenção ao alterar o código e observe que estamos usando o método getSerializable().
Como esse método retorna um objeto do tipo Serializable, fizemos o cast para Usuário conforme
estudamos nas aulas de Kotlin.
Como agora a variável “user” é do tipo Usuário, podemos acessar seus atributos como
user.nome e user.email tranquilamente. Se quiser brincar, altere a linha que configura o texto do
TextView para mostrar o nome e e-mail:
Esperamos que tenha ficado clara a vantagem de passar um objeto inteiro como parâmetro, ao
contrário de passar apenas uma simples variável.
TEMA 4 – INTENTS E PERMISSÕES
Uma Intent é o coração do Android e está presente em todos os lugares, ela representa uma
mensagem do aplicativo para o sistema operacional, solicitando que algo seja realizado. Portanto,
uma intent refere-se à intenção de realizar uma operação, como, por exemplo, abrir uma tela do
aplicativo. Embora na maioria das vezes usamos intents para esses objetivos mais simples, ela é
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 21/46
muito mais que isso. Com uma intent, podemos abrir telas de outros aplicativos como o de um email,
SMS, mapas etc.
Uma intent também é usada pelo sistema operacional para nos notificar de que algo aconteceu.
Por exemplo, ao receber uma mensagem de push (aquelas notificações),podemos interceptar essa
mensagem e fazer alguma tarefa. Isso tudo são casos mais avançados e que você vai aprender com o
tempo se mergulhar a fundo no mundo do desenvolvimento para Android.
Nos próximos exemplos, vou mostrar códigos de como criar algumas intents. Mas antes, vamos
criar um novo projeto, assim já aproveitamos para revisar isso. Crie o projeto pelo Android Studio da
mesma forma que mostrado na primeira aula com o wizard > File > New Project e escolha o
template Empty Activity. No nome do projeto, digite HelloIntents e o resto deixe com os valores
padrão.
No layout XML da activity do arquivo activity_main.xml, deixe o seguinte layout, com apenas um
botão para testarmos as intents.
Observe que foi dado o id btTeste para o botão, assim, podemos usá-lo para adicionar um
evento e chamar as intents que vamos brincar.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 22/46
Pronto! A estrutura de código para os próximos exemplos está criada, então, vamos continuar.
4.1 INTENTS SIMPLES
A primeira intent que vamos estudar é uma chamada simples que vai abrir o browser, basta fazer
a seguinte alteração no código:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 23/46
Feito isso, execute o projeto no emulador. Ao clicar no botão, o browser será aberto na página
do Google, como mostrado na próxima figura.
Figura 4 – Browser
Crédito: Khuruzero/Shutterstock.
No próximo exemplo, vamos passar como parâmetro a localização da Ópera de Arame em
Curitiba. Note que passamos os parâmetros com a URI geo: seguida da lat/lng e do zoom para o
Mapa que neste caso é 15.
Altere o código que chama a intent para ficar assim:
Desta vez, o aplicativo do Google Maps será chamado e mostrará a localização desejada.
Figura 5 – Google Maps
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 24/46
Crédito: Khuruzero/Shutterstock.
Até o momento, estudamos dois exemplos de chamadas de intents que abrem o browser e o
mapa, e vimos o quão útil podem ser essas chamadas.
Saiba mais
Existem várias outras chamadas de intents que podemos fazer e recomendamos que você
leia a documentação oficial sobre Intents Comuns, que são essas chamadas simples que abrem
outros aplicativos. Veja mais no link a seguir: <https://developer.android.com/guide/component
s/intents-common?hl=pt-br>.
4.2 INTENTS SEGURAS E PERMISSÕES
Agora vamos mostrar um exemplo mais complexo e já adiantamos que ele não vai funcionar de
primeira e o aplicativo vai travar. Vamos tentar fazer uma ligação telefônica usando a URI
'tel:número':
Altere o código que chama a intent mais uma vez:
https://developer.android.com/guide/components/intents-common?hl=pt-br
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 25/46
Ao chamar essa intent, o aplicativo vai travar conforme o esperado e teremos esta exceção no
LogCat. Tente ler a mensagem passo a passo e com atenção:
Podemos ver pela mensagem que a permissão foi negada pelo sistema (Permission Denial). Isso
aconteceu porque uma ligação é restrita pelo fato de que ela pode gerar custos para o usuário.
Sendo assim, antes de fazer uma ligação, precisamos pedir permissão para o usuário com um alerta
com este:
Figura 6 – Alerta
Crédito: Khuruzero/Shutterstock.
Antes de aprendermos a fazer isso no código, vamos estudar alguns conceitos sobre permissões.
Primeiramente, vá até a tela de configurações do aplicativo HelloIntents que acabamos de criar. Nas
últimas versões do Android, isso pode ser feito clicando e segurando no ícone do aplicativo por 2
segundos, depois selecione a opção App Info. Na tela de configurações, veja que esse aplicativo não
requisitou nenhuma permissão para o usuário.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 26/46
Figura 7 – Permissões
Crédito: Khuruzero/Shutterstock.
Sendo assim, o que precisamos fazer é configurar o aplicativo para solicitar esta permissão. A
primeira tarefa a fazer é adicionar a tag <uses-permission> no arquivo de manifesto. Essa tag define
as permissões necessárias para o aplicativo, ou seja, todos aqueles alertas que temos que mostrar ao
usuário para ele autorizar o uso de chamadas restritas. Tenha atenção, pois a configuração fica antes
da tag <application>.
● AndroidManifest.xml
Pronto, feito isso, execute o projeto novamente no emulador.
O resultado é que o aplicativo vai continuar travando. Mas a boa notícia é que, ao voltar na tela
de configuração do aplicativo, você verá que desta vez existe uma permissão que ainda não foi
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 27/46
autorizada, conforme podemos verificar na próxima figura.
Figura 8 – Permissão não autorizada
Crédito: Khuruzero/Shutterstock.
Para fazermos o primeiro teste e validar a intent que faz a ligação, clique na permissão de
telefone (Phone) e depois clique em Allow para aceitar essa permissão.
Figura 9 – Aceitar permissão
Crédito: Khuruzero/Shutterstock.
Muito bem. Acabamos de fazer um artifício técnico, conhecido popularmente como gambiarra,
para conceder uma permissão para o aplicativo. Isso significa que já podemos fazer a ligação
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 28/46
utilizando aquela intent.
Desta vez, ao clicar no botão que chama a intent, o aplicativo que faz as chamadas telefônicas
será aberto e vai iniciar a ligação. Legal, não é mesmo?
Figura 10 – Ligação
Crédito: Khuruzero/Shutterstock.
4.3 SOLICITANDO AS PERMISSÕES PELO CÓDIGO
O exemplo da ligação funcionou e foi importante para entendermos o que é uma permissão,
mas é claro que o correto é solicitar as permissões dentro do aplicativo, e é exatamente isso que
vamos fazer no próximo exemplo.
Para continuar, entre na tela das permissões novamente e, desta vez, clique em Deny para negar
a permissão e voltar ao estado inicial do aplicativo.
Figura 11 – Negar permissão
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 29/46
Crédito: Khuruzero/Shutterstock.
Feito isso, crie a classe PermissionUtils no projeto com o seguinte código. Veja que a classe foi
anotada com a palavra reservada object, portanto, ela é um singleton e pode ser utilizada com a
notação Classe.método(), conforme estudamos na aula de Kotlin.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 30/46
Com o tempo, você vai estudar e aprender mais sobre o código contido nessa classe. Por
enquanto, vamos aprender a utilizá-la, sendo assim, faça as seguintes alterações no código e leia os
comentários com atenção, pois as explicações estão no código.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 31/46
O objetivo deste código é mostrar o alerta de permissão para o usuário. Isso é feito nesta linha:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 32/46
Caso o método retorne false, sabemos que o alerta foi mostrado ao usuário e o aplicativo está
aguardando se ele vai aceitar ou não a permissão. Por isso, nesse momento, o botão é deixado
invisível, pois não podemos deixar o usuário clicar nele antes de aceitar a permissão.
Figura 12 – Permissão
Crédito: Khuruzero/Shutterstock.
Quando o usuário responder, o método onRequestPermissionsResult() é chamado para validar
as permissões, algo que estamos fazendo com esta linha de código:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 33/46
E por fim, caso o usuário tenha aceitado a permissão, o botão é deixado visível novamente, o
que significa que o usuário autorizou este aplicativo a fazer ligações telefônicas.
Conforme vimos, controlar as permissões do aplicativo não é uma tarefa muito simples, é um
trabalho bem delicado e que exige um certo refinamento. Neste exemplo simples, o botão apenas foi
deixado invisível, mas dependendo do caso, o tratamento poderia ser mostrar outro layout no lugar
do botão. O interessante é que aprendemos a usar a propriedade visibilityda View, e com ela,
podemos informar se uma view está visível ou invisível.
Como desenvolvedor, você precisa trabalhar a interface do aplicativo para não permitir que o
usuário chame alguma funcionalidade restrita se ele ainda não aprovou a permissão, pois se o fizer, o
Android lançará uma exceção.
Caso tenha um celular Android em mãos, uma sugestão é você entrar na tela de permissões do
WhatsApp e depois negar todas as permissões. Ao voltar ao WhatsApp, tente chamar alguma
funcionalidade restrita como gravar um áudio ou tirar uma foto. Você verá que o WhatsApp mostra
uns alertas elegantes para o usuário, ou seja, ele faz o controle se as permissões estão aceitas e as
trata devidamente.
TEMA 5 – TIRANDO UMA FOTO
Para finalizar nossos estudos sobre uma intent, vamos fechar com chave de ouro e tirar uma foto
com a câmera pelo aplicativo. Da mesma maneira que abrimos o browser e o Google Maps e depois
também fizemos uma ligação, podemos usar uma intent para abrir o aplicativo da câmera. A
diferença é que o aplicativo da câmera vai nos retornar a foto que foi tirada pelo usuário, portanto,
temos que aguardar esse retorno.
Atenção: este exemplo é mais complexo e vai exigir mais de você. Nele, vamos revisar quase
tudo o que já aprendemos, portanto, leve o tempo que precisar para estudar o código com calma.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 34/46
Para esta brincadeira, vamos criar um novo projeto chamado HelloCamera, da mesma forma
que fizemos nos exemplos anteriores. Altere o layout da activity para ter um botão na parte superior,
e uma imagem logo abaixo. O objetivo é clicar o botão para tirar a foto e depois mostrá-la no
ImageView.
● activity_main.xml
O interessante é que no layout XML criamos um botão com o ImageButton, ou seja, é um botão
que vai mostrar uma imagem de uma câmera. Para isso, usamos um recurso nativo do Android que já
tem essa figura: @android:drawable/ic_menu_camera. Observe também que as duas views possuem
ids, portanto, podemos acessá-las no código.
Com o layout criado, vamos continuar. Primeiro, vamos digitar todos os arquivos necessários
para o exemplo funcionar, e depois vamos estudar o código, combinado?
A seguir, temos o código da activity que dispara a intent para abrir a câmera. O código está
comentado, leia com atenção.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 35/46
● MainActivity.kt
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 36/46
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 37/46
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 38/46
Como já estudamos o que é uma intent, permissões e o método onSaveInstanceState(bundle),
a maior parte do código você deverá entender sem problemas. Observe que logo no início do código
estamos solicitando a permissão para utilizar a câmera. Caso a permissão seja negada, o botão ficará
invisível.
A classe PermissionUtils é exatamente a mesma que usamos no exemplo da ligação telefônica,
é só copiar para este projeto. E para a permissão funcionar, adicione no arquivo de manifesto a
seguinte configuração:
● AndroidManifest.xml
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 39/46
Mas para o código compilar, ainda precisamos criar o arquivo ImageUtils, que vai fazer o
dimensionamento da foto antes de mostrar no ImageView, pois as câmeras, atualmente, tiram fotos
com muitos pixels, e para economizar memória, os aplicativos fazem este redimensionamento.
 O código desta classe está com comentários em inglês, pois foi tirado da documentação oficial
.
● ImageUtils.kt
[1]
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 40/46
Pronto, estamos quase terminando, falta apenas uma configuração. Saiba que, quando
chamarmos a intent para abrir a câmera, vamos passar como parâmetro o caminho de um arquivo
para que a foto seja salva. Esse arquivo ficará numa pasta privada do nosso aplicativo:
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 41/46
Mas, por questões de segurança, a partir do Android 7 (Nougat), o Android não permite que a
câmera ou qualquer outro aplicativo salve arquivos nessa pasta sem darmos acesso. Portanto, as
configurações que vamos fazer agora é dar acesso ao aplicativo da câmera para gravar arquivos na
pasta privada do nosso aplicativo.
Para isso, crie uma pasta /res/xml conforme indicado na figura e o arquivo provider_paths.xml.
● /res/xml/provider_paths.xml
Figura 13 – Pastas
Por último, temos que criar esta configuração no arquivo de manifesto.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 42/46
● AndroidManifest.xml
Pronto, terminamos! Vamos ver o projeto funcionando?
Ao executar o projeto no emulador, o primeiro passo é solicitar ao usuário a permissão para
utilizar a câmera.
Figura 14 – Permissão
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 43/46
Crédito: khuruzero/Shutterstock.
Essa parte do código é exatamente igual ao exemplo anterior que fizemos e não iremos explicá-
la, portanto, revise o código com atenção.
Ao clicar no botão para tirar uma foto, o método onClickCamera() é chamado. Nele, veja que
criamos o arquivo no qual queremos que a foto seja salva. Logo depois, é criada uma intent com
ação MediaStore.ACTION_IMAGE_CAPTURE, que será interceptada pela câmera. Você verá no
código que ao criar a intente, é usado o parâmetro MediaStore.EXTRA_OUTPUT para informar o
caminho do arquivo que a câmera vai receber como argumento.
Feito isso, a câmera será chamada e você poderá tirar uma foto, conforme mostra a figura.
Observação: o emulador possui um bug em que, na primeira vez, a foto não funciona. Se isso
acontecer, clique no botão voltar para fechar a câmera e tente novamente.
Figura 15 – Câmera
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 44/46
Crédito: khuruzero/Shutterstock.
Depois de tirar a foto, clique no botão de confirmar dentro do aplicativo da câmera. Isso vai
fechar a câmera e devolver o arquivo para nosso aplicativo. O resultado é que o método
onActivityResult() será chamado. Ele é um método que é chamado quando um aplicativo retorna
dados para outro. Nós não havíamos comentado, mas veja que, ao chamar a intent da câmera, foi
utilizado o método startActivityForResult() justamente por isso. Veja no método onClickCamera().
O método onActivityResult() contém a lógica necessária para mostrar a foto no ImageView.
Veja o código do método showImage(file). Nele, estamos chamando a classe ImageUtils para fazer
o redimensionamento da foto, conforme já explicado. O resultado depois de tirar a foto podemos ver
na figura a seguir:
Figura 16 – Foto
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 45/46
Crédito: khuruzero/Shutterstock.
Por último, faça um teste e gire a tela do emulador para horizontal. O resultado é que a foto é
salva e não perdemos o estado do aplicativo. Isso só foi possível porque o método
onSaveInstanceState(bundle) foi implementado, conforme já estudamos. Nele, salvamos o arquivo
"file" e, depois, quando o Android recriou a activity, lá no método onCreate(bundle), esse arquivo foi
recuperado e mostrado automaticamente na tela.
Figura 17 – Tela na horizontal
Crédito: khuruzero/Shutterstock.
FINALIZANDO
Nesta aula, estudamos o ciclo de vida de uma activity e depois aprendemos conceitos
importantes sobre uma intent, a passagem de parâmetros entre telas e o controle de permissões
paras as intents restritas. Por fim, aprendemos a tirar uma foto com a câmera.
REFERÊNCIAS
ANDROID DEVELOPERS. Documentação oficial - Intents comuns. Disponível em:
<https://developer.android.com/guide/components/intents-common?hl=pt-br>.
_____. Documentação oficial – Câmera. Disponível em: <https://developer.android.com/
training/camera/photobasics>.
_____. Android Training – Loading Large Bitmaps Efficiently. Disponívelem:
<https://developer.android.com/topic/performance/graphics/load-bitmap.html>.
15/03/2022 18:34 UNINTER
https://univirtus.uninter.com/ava/web/roa/ 46/46
LECHETA, R. Android Essencial com Kotlin. 2. ed. 2018.
 Disponível em: < https://developer.android.com/training/camera/photobasics>. Acesso em:
22 jan. 2021.
[1]

Outros materiais