Olá! Sou o Ricarth Lima e serei seu instrutor em mais um curso no fascinante mundo do Flutter.
Audiodescrição: Ricarth é um homem com cabelo Black Power e barba castanho-escuro. Usa óculos de grau com armação transparente e uma camiseta preta. Ao fundo, uma parede lisa com iluminação degradê do rosa ao roxo. Ao lado esquerdo, duas prateleiras suspensas com livros e itens de decoração. Ao lado direito uma prateleira com livros e uma cafeteira.
Boas-vindas ao curso de Flutter Integrações com a Câmera!
Vamos explorar o projeto que desenvolveremos. Estamos não com o emulador, mas sim a reprodução de um dispositivo físico que está em nossas mãos. Afinal, utilizaremos uma câmera real.
Ao clicar no botão "Entrar" para fazer um registro no Banco D'Ouro, desenvolvido na formação Dart, a pessoas usuárias vai inserir seus dados, como nome, data de nascimento e endereço. No entanto, o que importa para nós neste curso é desenvolver o comportamento necessário para a pessoa conseguir fotografar o documento e o rosto, elementos essenciais para o banco confirmar que a pessoa que está abrindo a conta é, de fato, quem afirma ser no cadastro.
Ao clicar em fotografar o rosto, a câmera será ativada. Vamos aprender a controlá-la, inicializá-la, e a colocar todo o guia ao redor ou sobre a câmera. Além disso, capturaremos uma imagem que, mesmo que inicialmente não fique perfeita, poderá ser confirmada e utilizada como informação no cadastro.
Não é necessário muito esforço para perceber a importância de aprender a usar a câmera no Flutter. Muitos aplicativos que utilizamos diariamente, seja em redes sociais ou para segurança, como no caso de um banco, fazem uso da câmera. Portanto, é fundamental incluir esse conhecimento em nosso repertório no Flutter.
Outro ponto importante são os pré-requisitos. É necessário ter concluído a formação de Dart e a formação de Flutter. Com esses conhecimentos, será possível acompanhar adequadamente nosso curso de integrações com a câmera.
Estamos bastante animados para começar, então vamos colocar a mão na massa!
Agora que conhecemos nosso projeto e entendemos nossos objetivos, vamos pôr a mão na massa. A primeira pergunta que precisamos responder é: quais são as câmeras às quais nosso dispositivo tem acesso? Precisamos de uma lista das câmeras com as quais poderemos trabalhar, sejam elas frontais ou traseiras.
Falando sobre o dispositivo, é importante esclarecer que, neste curso, e em todos os outros que lidam com hardware físico, como é o caso da câmera, recomendamos fortemente o uso de um dispositivo físico. O que está sendo espelhado na tela é apenas um espelhamento do dispositivo físico, não um emulador.
Isso é excelente por duas razões. Primeiro, porque nos aproxima da experiência que a pessoa usuária final terá. Segundo, evita diversos problemas e bugs, já que um dispositivo emulado também emula características físicas, como a câmera, que não será real. Portanto, recomendamos o uso de um dispositivo físico. Haverá um "Para Saber Mais" que relembrará como conectar um dispositivo físico ao VS Code.
Sabendo disso, vamos instalar o plugin Camera
, que será responsável por todas as ações relacionadas à câmera neste curso. Para isso, vamos ao VS Code, parar a execução do código, abrir o console de depuração com "Ctrl + J", e rodar o comando flutter pub add camera
.
flutter pub add camera
Esse comando instalará o pacote do pub.dev, que possui integração com a parte nativa do Android, por isso é chamado de plugin. Após isso, fechamos o terminal com "Ctrl + J".
Um detalhe importante é que precisamos fazer uma configuração fora da parte de Flutter, entrando na parte nativa do projeto Flutter. No explorador, vamos à pasta "Android", procuramos por "app" e clicamos no arquivo build.gradle
. Dentro desse arquivo, procuramos pela linha onde está escrito minSdk
, apagamos o flutter.minSdkVersion
e passamos 21
, conforme recomendado pelo plugin.
minSdkVersion = 21
Salvamos o build.gradle
, fechamos tudo, exceto o arquivo main
, e rodamos o projeto para verificar se tudo está funcionando corretamente. Se a aplicação rodar sem problemas, significa que a instalação do plugin e a configuração no build.gradle
foram bem-sucedidas. Deu certo.
Clicamos no botão "Sem conta? Registrar-se agora!" e somos encaminhados para a página de formulário. Trabalharemos agora nessa tela de cadastro, mais especificamento nos campos em que solicitam uma foto do documento e rosto.
No VS Code, pressionamos "Ctrl + B" e acessamos "ui > registration" e abrimos o arquivo registration_screen.dart
. No fim do código, há um método pré-pronto chamado _handleCameraClicked()
, que lida com o clique no botão de abrir a câmera.
Nesse caso, vamos usar o método availableCameras()
do plugin Camera
. Se o analisador do Dart demorar para fazer a importação automática, podemos fazê-la manualmente. No início do arquivo, escrevemos:
import 'package:camera/camera.dart';
Com o método availableCameras()
, que é assíncrono e retorna uma lista de CameraDescription
, podemos prosseguir. Na linha 173, criamos uma lista de CameraDescription
chamada cameras
e a inicializamos com await availableCameras()
.
Com essa lista, vamos primeiro imprimir a List Cameras
. Sabemos que isso é uma lista e que o CameraDescription
se assemelha a um map. Para facilitar a visualização, vamos utilizar o método toString
na List Cameras
e aplicar um replaceAll("),","), \n")
, permitindo que a saída seja exibida em múltiplas linhas.
void _handleCameraClicked(
BuildContext context,
RegistrationViewModel viewModel, {
bool isDocument = true,
}) async {
List<CameraDescription> listCameras = await availableCameras();
print(listCameras);
print(listCameras.toString().replaceAll(",", ",\n"));
if (isDocument) {
// TODO: Abrir câmera para fotografar documento
} else {
// TODO: Abrir câmera para fotografar selfie
}
}
Vamos salvar, reiniciar a aplicação, abrir o console de depuração e o visualizador. No entanto, não utilizaremos tanto o visualizador, pois ele gera warnings que não são bem-vindos no momento. Vamos usar o dispositivo físico. Após clicar em "Sem Conta? Registre-se agora!", arrastamos para cima e clicamos em "Fotografar rosto", nisso algumas ações ocorrem.
Inicialmente, o primeiro print é difícil de visualizar, mas os subsequentes, com a quebra de linha, são mais claros. Identificamos quatro câmeras: duas frontais e duas traseiras, com as direções de lente "Back" e "Front". Os valores 90 e 270 indicam a rotação, o que será útil no futuro. O CameraDescription
contém o ID da câmera, a seleção entre traseira ou frontal e o número, resolvendo nosso problema de identificar as câmeras disponíveis no dispositivo.
Build.Gradle
OBuild Gradle
faz parte dos arquivos nativos que normalmente não exploramos no Flutter. Primeiro, precisamos entender o que é código nativo. O Flutter é multiplataforma e híbrido, criando aplicativos para iOS e Android, além de suportar Linux, Chrome OS, Windows, Mac OS, entre outros. Isso requer códigos nativos em seu interior.
No VS Code, ao explorar o projeto Flutter, percebemos que não existe apenas a pasta "lib". Há várias outras pastas, como "Android", "iOS", "Linux", "Mac OS" e "Web", relacionadas ao caráter multiplataforma e híbrido do Flutter. Por exemplo, na pasta "Web", encontramos partes de um site, como HTML, JavaScript e CSS. Na pasta "Windows", há códigos como make. Na pasta "Android", encontramos códigos Java, Kotlin e XML, essenciais para cada tecnologia, utilizados pelo Flutter durante o build.
O Build Gradle
é parte do código nativo do Android, responsável pela configuração do Gradle, uma ferramenta de automação usada para compilar, testar e empacotar aplicativos. Quem já programou para Android nativo conhece o Gradle. No Flutter, precisamos conhecê-lo para situações que exigem código nativo.
O Build Gradle
é responsável por plugins e configurações iniciais do Android, como o minSDK
e as dependências do projeto, semelhante ao pubspec.yml
. No VS Code, ao acessar "app > build.gradle", observamos que o código começa com os plugins usados no build do aplicativo. Entre as linhas 8 e 40, há configurações do Android, incluindo versões de SDK, versão de compilação, versão mínima e namespace, úteis para publicação na Play Store. Também definimos dependências, como pacotes do Firebase, que precisam estar presentes no código nativo além do ProSpec.yml
.
O MinSDK
define a versão mínima do Android que o aplicativo suportará. Com a evolução do Android, novas versões e SDKs são lançados. Definimos a versão mínima, neste caso, a 21, por recomendações do plugin. Ao instalar um plugin, é importante verificar no readme do pub.dev se há instruções específicas, como a necessidade de uma versão mínima do Android. A versão 21 foi recomendada devido a funcionalidades necessárias para o funcionamento do plugin.
Caso tenha ficado com alguma dúvida, consulte nosso fórum e o canal do Discord para discutir o assunto. Vamos continuar!
Agora que conseguimos listar nossas câmeras, chegou a hora de usar alguma delas para inicializar, abrir, configurar e até mesmo tirar fotos. Para realizar essas ações, não utilizamos o CameraDescription
, mas sim um objeto do plugin Camera chamado CameraController
. Ele será o centro de tudo que faremos com nossa câmera.
No arquivo registration_screen.dart
, faremos algumas mudanças iniciais. Começamos apagando o print(listCameras)
, ele não é útil devido à sua má formatação. O print()
que sobrou pode ser útil no futuro, caso precisemos verificar alguma parte da câmera ou algum detalhe, então vamos mantê-lo por enquanto.
As linhas de To Do estão verificando basicamente se o clique veio do documento ou da selfie no nosso aplicativo. Não vamos utilizá-las por enquanto, então vamos comentá-los.
Próximo à linha 176, podemos criar um CameraController
. Vamos chamá-lo de cameraController
e ele receberá um CameraController()
. Vamos colocar uma vírgula no final da linha 177, antes do parêntese, para identificar melhor e discutir cada um dos atributos que passamos para o CameraController
.
O primeiro é um CameraDescription
, então precisamos decidir qual câmera queremos utilizar. Para isso, vamos verificar no console de depuração com um "Ctrl + J". As câmeras ainda aparecem listadas: a primeira é uma câmera traseira e a segunda é uma câmera frontal. Vamos começar pela frontal, pois será mais fácil visualizar os detalhes. Com um "Ctrl + J", verificamos que o print
foi útil. Na Description
, vamos passar listCameras[1]
na posição 1, já que é a nossa segunda câmera.
Na linha 178, vamos definir no ResolutionPreset
qual é a resolução que queremos para abrir essa câmera. Isso é um Enum, ResolutionPreset
, e ao verificar os valores desse Enum, percebemos que são resoluções semelhantes às que vemos no YouTube, relacionadas à qualidade. Normalmente, chamamos de qualidade porque uma resolução menor, ou seja, uma quantidade de pixels menor, resulta em uma qualidade inferior. A resolução está relacionada à quantidade de pixels. Assim, a High é 720, a Low é por volta de 240, a Max é o máximo que a câmera pode entregar, a Medium é 480, a Ultra High é 2160, e a Very High é 1080p.
A opção 1080p é uma resolução interessante, mas para evitar problemas de compatibilidade, e considerando que nosso aplicativo não precisa de gravações elaboradas, já que não é um aplicativo de vídeo, optamos por selecionar a qualidade High. Um atributo que podemos configurar, embora não seja obrigatório, é o enableAudio
. Vamos defini-lo como false
, pois, por padrão, ele vem como true
.
Esse atributo permite que a câmera utilize o microfone do dispositivo, além da própria câmera. Isso é útil se estivermos gravando vídeos, pois é interessante ter o áudio junto com o vídeo. No entanto, como nosso objetivo é apenas tirar fotos, não faz sentido manter essa opção ativada, pois isso geraria uma solicitação de permissão desnecessária para o uso do microfone. Portanto, vamos definir como false
. Se estivermos gravando vídeos, podemos deixá-lo como true
.
Mas, essa configuração não inicializa a câmera. O que fizemos, da linha 176 até a 180, foi declarar o Camera Controller
e inicializar o objeto Camera Controller
. Para inicializar a câmera e informar ao Android que ela deve estar funcionando, precisamos executar o comando na linha 182: aameraController.initialize()
. Como essa função é assíncrona, utilizamos await
antes dela. Ao passar o mouse sobre a função, verificamos que é um Future, confirmando que é assíncrona.
bool isDocument = true,
}) async {
List<CameraDescription> listCameras = await availableCameras();
print(listCameras.toString().replaceAll("),", "),\n"));
CameraController cameraController = CameraController(
listCameras[1],
ResolutionPreset.high,
enableAudio: false,
);
await cameraController.initialize();
// if (isDocument) {
// // TODO: Abrir câmera para fotografar documento
// } else {
// // TODO: Abrir câmera para fotografar selfie
// }
}
}
Salvamos as alterações e pressionamos F5 para rodar o aplicativo. Como estamos rodando após ter parado para fazer configurações de build, o processo de abertura pode demorar um pouco. Após a abertura, com o aplicativo em execução, clicamos em "Sem Conta? Registre-se Agora!" e, em seguida, na opção para abrir a câmera, seja para fotografar documento ou rosto. Ao clicar, o aplicativo solicita permissão, informando que o "Flutter Banco D'Ouro deseja gravar vídeos e tirar fotos". Nesse caso, selecionamos a opção "Durando o uso do app".
Após a permissão, uma câmera aparece no canto superior direito, indicando que o Android está usando a câmera, mas nada mais acontece. Isso é esperado, pois o controlador apenas inicializou a câmera. Para visualizar a câmera e obter a resposta em tempo real, precisamos usar um widget na tela, o que faremos na sequência. Até lá!
O curso Flutter: integrações com a câmera possui 157 minutos de vídeos, em um total de 50 atividades. Gostou? Conheça nossos outros cursos de Flutter em Mobile, ou leia nossos artigos de Mobile.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.