GPS em segundo plano no Android sem perder o motorista
O celular do taxista passa o dia com a tela apagada, preso no painel, entrando em túneis. O que o Android faz com a localização nessas horas, e o que fizemos para continuar sabendo onde o carro está.
Este é o 3º artigo da série “Construindo o Carioca Taxi”.
Para o passageiro, o app é aberto, usado e fechado. Para o motorista, o app fica ligado o dia inteiro: o celular preso no painel, a tela apagando, o Waze ou o Google Maps na frente, a bateria esquentando. E durante todo esse tempo precisamos saber onde o carro está: para oferecer a corrida ao motorista mais perto e para mostrar ao passageiro o táxi chegando.
O Android, com razão, faz de tudo para economizar bateria. O problema é que, para ele, um app com a tela apagada é justamente o primeiro candidato a perder o GPS. Este é o terceiro artigo da série.
O básico que precisa estar certo
Serviço em primeiro plano
No Android moderno, a única forma confiável de receber a localização com a tela apagada é um serviço em primeiro plano: o app declara que está fazendo algo que o usuário sabe, e o sistema mostra uma notificação fixa enquanto isso acontece. A nossa diz "Você está online. Localização ativa." Ela é a promessa de que o app não some quando a tela apaga.
"Permitir o tempo todo"
A permissão de localização tem dois níveis: só com o app aberto, ou o tempo todo. O segundo, a partir do Android 11, não pode ser pedido numa janelinha. O sistema leva o usuário para as Configurações. A Play Store também exige que o app explique antes, com as próprias palavras, por que precisa disso.
Então não pedimos a permissão de surpresa. Antes de o motorista ficar online pela primeira vez, ele passa pela tela Preparar o aparelho, que confere cada item, explica e só então abre o pedido do sistema:
- a localização "o tempo todo";
- as notificações;
- a economia de energia desligada.
O vilão que não estava no código
Durante os testes, a localização com a tela apagada passou a chegar a cada 7 segundos em vez de a cada segundo, e com o triplo do erro de posição. Gastamos várias rodadas de teste investigando o nosso código e o da biblioteca de localização. A causa estava no celular: a Economia de energia estava ligada.
Com a Economia de energia ligada, o Android adota a política "GPS desligado com a tela apagada" e passa a entregar posições aproximadas, bem de vez em quando. E o detalhe que mais surpreendeu: colocar o app na lista de exceções da bateria não muda isso. Conferimos com o app comprovadamente isento e a economia ligada, e o resultado foi o mesmo.
A lição foi de processo: antes de investigar o código, confira o estado do aparelho. Por isso a economia de energia virou um dos itens da tela Preparar o aparelho, que avisa o motorista quando ela está ligada.
Do lado do servidor: quando o silêncio é informação
Mesmo com tudo certo, o sinal vai cair: túnel, garagem, celular desligado, rede ruim. A pergunta passa a ser quanto tempo sem posição significa "não sei onde ele está".
Cada motorista tem um pequeno objeto no servidor (um Durable Object, como contamos no primeiro artigo) que guarda a hora da última posição e mantém um único alarme. Se o alarme dispara e nenhuma posição nova chegou em 20 segundos, o estado vira "sinal perdido". O passageiro vê isso no app, e o carro para de "andar" no mapa por estimativa. Quando uma posição chega, volta ao normal.
O alarme só é reagendado quando dispara, e a hora da última posição vai para o disco no máximo a cada 5 segundos. Um motorista mandando posição o tempo todo custa quase nada.
Para as horas online, que entram nos ganhos e na performance do motorista, há outra regra. Uma sessão sem nenhuma posição por 10 minutos é fechada na hora da última posição recebida, porque o app morreu ou o celular desligou. Mas o servidor não tira o motorista do ar sozinho por isso. Quem decide ficar online é o motorista. Se o servidor o desligasse, ele pararia de receber corridas sem saber por quê.
Túneis: estimar com cuidado
No Rio, perder o GPS é rotina: Rebouças, Santa Bárbara, Túnel Novo. Na navegação dentro do nosso app, o carro precisa seguir no mapa sem o GPS, mas sem inventar movimento quando o trânsito parou dentro do túnel.
Usamos o acelerômetro só durante a navegação. Não para calcular a posição (isso acumula erro muito rápido), mas para responder uma pergunta mais simples: o carro está balançando ou está parado?
- Balançando: o carro segue na mesma velocidade de antes, pela rota, até o sinal voltar.
- Quieto por dois segundos: o carro para no mapa.
- Na dúvida: fazemos o de sempre.
A medida que usamos não depende de como o celular está preso: é quanto o tamanho da aceleração varia em dois segundos. Os limites ainda são estimativas, e só a rua vai confirmá-los. Esse é um dos ajustes que fazemos depois das primeiras corridas reais.
Testar no celular, não só no emulador
Tudo o que contamos aqui só aparece num aparelho de verdade, num uso de verdade:
- economia de energia;
- tela apagada por meia hora;
- uma tela dobrável com dois displays, em que o print de tela sai preto se você pedir o display errado.
Por isso nenhuma mudança no app do motorista é dada como pronta sem passar por um celular físico. E, de preferência, por um segundo celular de outra marca, porque cada fabricante tem a sua própria ideia de "economizar bateria".
Considerações finais
GPS em segundo plano não é um recurso que se liga. É um acordo com o sistema operacional, que tem os próprios interesses, e com o motorista, que precisa entender por que o app pede o que pede. O que funcionou para nós:
- fazer o básico certo: serviço em primeiro plano e permissão explicada;
- conferir o estado do aparelho antes de culpar o código;
- tratar o silêncio como informação, do lado do servidor;
- estimar só o que dá para estimar com segurança.
Este é o último artigo desta primeira série. Se você também trabalha com localização em apps Android e passou por algo parecido, queremos ouvir.