Python no Android

Motivação

Não adianta tentar negar: se você quer uma aplicação que rode direito no Android, você, programador-não-Java, precisa sujar as mãos e enfrentar o velho Androidão de frente, meter a mão na massa e se embrenhar pelo mundo assombroso do Java do Android (argh!), das bibliotecas, da IDE, das licenças e, enfim, de todo o ferramental necessário para se escrever aplicações nativas.

Eu atualmente tenho dois projetos cuja base de funcionamento são aplicações que rodem em celulares de gente normal. Um deles envolve extrair dados de praticamente todos os sensores presentes no aparelho, enquanto o outro baseia-se mais em notificações personalizadas por usuário.

Sobre este último, eu cheguei a considerar criar Progressive Web Apps. Cheguei a pesquisar sobre Push Notifications. Mas, sinceramente, não senti que as alternativas eram boas o bastante e, no fim das contas, tenho percebido que dificilmente eu escapo de ter que pelo menos conseguir escrever aplicações nativas para Android.

Até para o meu trabalho atual é interessante eu possuir essa habilidade…

Neste artigo apresento como escrever aplicações nativas Android usando Python e as ferramentas do projeto PyBee.

Começando pelo desagradável

Android Studio

Antes de mais nada, baixe o Android Studio. Sério. Baixe e já comece agora o processo de instalação. Há uma grande quantidade dados a serem baixados, então é melhor que você deixe isso para ser feito em background.

Segue o link para o download:

https://developer.android.com/studio/index.html#downloads

Download

Esse link para download é muito rápido e consegue “engargalar” a conexão da minha máquina toda vez. Quanto a isso, parabéns para a Google…

Caso você não queira entupir a banda da sua rede com esse download, experimente usar isso:

wget --limit-rate=100k 'ᐸlink-para-download-copiado-do-browserᐳ'

“Instalação”

Eu costumo instalar essas aplicações “avulsas” no meu diretório ~/Apps/ . Logo, o Android Studio foi jogado em ~/Apps/android-studio .

cd ~/Apps
unzip ~/Downloads/android-studio-ide-*-linux.zip

(O conteúdo do zip já está todo dentro de um diretório chamado android-studio , então não precisa se preocupar em criar este diretório previamente.)

Java

Curiosamente, eu não tinha nenhum Java (JRE/JDK) instalado na minha máquina pessoal. Então, só para garantir, certifique-se de que existe um comando java disponível na sua máquina.

which java && echo “Beleza, tem java”

Se não…

apt-get install openjdk-8-jre # No Linux Mint, pelo menos.

Baixando o Android SDK

Pois é, esse Android Studio meio que só serve para se baixar o Android SDK…

Como o download é grande e consome muita banda, eu uso um programinha chamado Trickle para limitar o uso de rede do Android Studio:

sudo apt-get install trickle -y
trickle -d 1000 -u 200 ~/Apps/android-studio/bin/studio.sh
# Agora espera, porque ~Java é rápido~.

Quando chegar a hora, vá direto para a instalação “Custom”:

android studio install type

Eu não gostaria de ter um diretório ~/Android , então eu faço questão de jogar a SDK também sob ~/Apps :

android studio components setup

Versão 27?

A versão que realmente precisaremos, pelo menos atualmente (finalzim de 2017) é a 25. Mas por mais que tenhamos escolhido uma instalação “Custom”, o Android Studio não vai deixar você baixar somente a 25 agora. Porque ele é estúpido. Você será obrigado a baixar um caminhão de coisas da versão 27 para somente depois conseguir instalar a 25, porque o Android Studio não permite que você primeiro configure somente o diretório onde o SDK deverá ficar para somente depois fazer o download do que quer que você precise. Você é obrigado a fazer tudo numa tacada só.

Então deixa aí baixando o que precisa e vá preparar um café.

Teu trabalho aqui está feito, Android Studio

Agora que você tem o Android SDK na sua máquina, pode jogar o Android Studio no lixo.

A Dança das Licenças

You have not accepted the license agreements of the following SDK components:

Para evitar de dar de frente com o erro acima na hora de empacotar tua aplicação, você ainda precisa rodar alguns comandos (que, inclusive, instalam as coisas que você precisa para poder criar tua aplicação):

cd ~/Apps/android-sdk/tools/bin
./sdkmanager --install "build-tools;25.0.2"
./sdkmanager --install "platforms;android-25"
./sdkmanager --install "system-images;android-25;google_apis;x86_64"
./sdkmanager --licenses

Veja que esses comandos criarão o diretório licenses dentro de ~/Apps/android-sdk/ . Na hora de construir sua aplicação, é importante que esse diretório esteja sob o $ANDROIDHOME (ou seje: garanta que essa variável de ambiente esteja apontando para o ~/Apps/android-sdk/ ou copie o diretório licenses para onde quer que $ANDROIDHOME esteja apontando).

Ah, essa mensagem, aqui:

Warning: File /home/ᐸwhoeverᐳ/.android/repositories.cfg could not be loaded.

É normal e não atrapalha em nada. Se você ficar incomodado com ela, basta criar o arquivo em questão, vazio mesmo.

Dependências de sistema

Você precisará instalar mais alguns pacotes, ainda:

sudo apt-get install aapt adb openjdk-8-jdk

E prosseguindo para o útil

Depois de ter se metido nesse mundinho miserável, eu sugiro que você tome um bom banho, porque agora vamos voltar ao universo normal e trabalhar com Python e software livre de verdade.

Ou, pelo menos, o quanto for possível…

Projeto base

Usei como base o projeto a seguir:

https://github.com/eliasdorneles/tictactoe-voc

É bom pegar alguma aplicaçãozinha pronta, porque além de estudar o código fonte, você não precisa se preocupar em descobrir como começar. Além de ter em mãos algo que funciona, o que já serve para te ajudar quando você começar a explorar mais e acabar quebrando tudo sem saber direito por que.

O único “requirement” desse projeto é o briefcase , que é o responsável por correr atrás do que for necessário para você conseguir empacotar sua aplicação para o sistema que você queira — que, no nosso caso, será o Android.

O briefcase é parte do projeto PyBee. No cerne do “empacotamento para Android” está outro projeto, o VOC, que é um “transpiler” de Python para Java.

https://pybee.org/project/projects/tools/briefcase/

Transpiler?

A parte interessante do VOC é que ele não faz tradução de AST ou da linguagem em si, como é o caso de outros projetos (vide Elixir, por exemplo). O VOC faz“transpilação de bytecode”. Ele pega o “assembly” do Python e transforma no “assembly” da JVM.

https://pybee.org/project/projects/bridges/voc/

Rodando o emulador

Isso aqui funcionou para mim:

~/Apps/android-sdk/emulator/emulator @Nexus_5X_API_27_x86 -data ~/Apps/android-sdk/system-images/android-25/google_apis/x86_64/userdata.img

Esse nome (Nexus5XAPI27x86) eu peguei rodando o seguinte comando:

~/Apps/android-sdk/tools/bin/avdmanager list | less

Curiosamente, o emulador não conseguiu terminar o boot na primeira tentativa. Matei-o com ctrl+c, iniciei novamente e, nessa segunda vez, funcionou okay.

android emulator booted

O emulador deve terminar o boot e chegar nesse Lançador.

Empacotando

export ANDROID_HOME=$HOME/Apps/android-sdk/
export $LD_LIBRARY_PATH=~/Apps/android-sdk/emulator/lib64/qt/lib

time python3 setup.py android -s

O comando acima fará o empacotamento para Android. O parâmetro -s fará com que não somente seja feito o build como também o run , para você já poder testar.

Caso ocorra algum erro e você queira tentar rodar a app novamente sem ter que fazer todo o build novamente:

cd android
./gradrew run

Não funciona, mas funciona

O gradle não conseguiu botar a app para rodar no emulador, mas reparei algo interessante nas mensagens de depuração:

Installing APK 'android-debug.apk' on 'Nexus5XAPI27x86(AVD) – 8.1.0' for android:debug Installed on 1 device.

Então abri a lista de aplicações na tela do emulador (aquela setinha pra cima bem discreta logo acima do ícone do Google Chrome) e lá estava o TicTacToe!

android emulator with tictactoe app

Iniciei a aplicação e ela rodou do jeito que deveria.

Entretanto, numa terceira tentativa, por acaso, enquanto eu fuçava pelas configurações do Android do emulador, o gradlew conseguiu botar a app para rodar no emulador.

Vai entender…

Rodando e depurando

Essa aplicação, o TicTacToe (que é o “jogo da velha”), não funcionou como esperado. O que até foi positivo, porque tentando descobrir o motivo, acabei aprendendo um pouco sobre as limitações do VOC.

Naquele ciclo de “mexe aqui, testa, mexe ali, testa”, acabei com essa linha de comando bem útil:

rm -rf android && time python setup.py android -s && adb logcat 'Python:* *:E'

Aquele último comando, adb logcat, mostra as mensagens de erro que estão pipocando lá no emulador do Android.

Próximos passos

Vou encerrar o artigo por aqui, porque o que você tem em mãos já é suficiente para começar a escrever alguma coisa com Python a ser rodada nativamente no Android.

E eu mesmo tenho muito a aprender, ainda (viu o nome da série? “Aprenda comigo”. Literalmente. Vamos juntos nessa caminhada). O VOC tem algumas limitações, como a não implementação do .format das strings (e muito menos as “f-strings”) e um ou outro comportamento que fogem do que se esperaria de uma implementação tradicional do Python.

No próximo artigo quero apresentar uma aplicação que contenha vários exemplos de uso das capacidades do aparelho, como o acelerômetro, a câmera, permissões, acesso a disco, etc.

Só preciso descobrir como.

Então, até o próximo artigo!


Este artigo foi originalmente escrito em 23/12/2017