quinta-feira, 11 de fevereiro de 2016

Como instalar um aplicativo apk Android no cartão SD Card

Introdução:
Instalar uma aplicação Android no cartão SD Card ao invés da memória interna do dispositivo é um recurso muito útil, sem dúvida.
Via de regra, é muito mais barato comprar um parelho com menos memória e um cartão do que um já com toda a memória.
Normalmente, é possível instalar ou mover a aplicação para o cartão e esse procedimento é bem simples, na verdade.
Basta entrar em Configurações -- App e clicar sobre o aplicativo:

Agora,basta clicar no botão "mover para o cartão SD" e pronto!
Ops... nem sempre o botão está aceso. E agora?

Hora de hack3ar...
Atenção: Esse procedimento pode ser considerado como violação de direito autoral, sei lá, e não há garantias de que funcione em todos os casos. Não deve ser usado para piratear nem fazer engenharia reversa. Faça por sua conta e risco.

Como funciona:
Uma aplicação Android é instalada a partir de um arquivo .apk que nada mais é do que um arquivo zip assinado. Dentro dele, há um arquivo chamado "androidManifest.xml":


É nele que se encontram informações como quais recursos a aplicação tem acesso, nomes, informação sobre versão, ícone, etc. Dentre elas, existe uma informação específica que nos interessa:

android:installLocation

Entretanto, essa informação é opcional. Se o desenvolvedor for preguiçoso, não vai coloca-la e, portanto, vale o default que é "memória interna".
O que proponho nesse artigo é simplesmente inserir essa informação no AndroidManifest.xml para permitir a instalação no SD Card.

Resumindo, os passos são:
  1. Baixar a aplicação no PC
  2. Descompactar o apk
  3. Aplicar as correções ao AndroidManifest.xml
  4. Recompactar o apk
  5. Assinar o apk
  6. Instalar a aplicação no dispositivo
Mãos a obra
Primeiro, precisamos baixar a aplicação do GooglePlay Store sem ser no dispositivo. Existem várias maneiras de se fazer isso, e eu optei por usar um programa para PC chamado Racoon. Entre no link e baixe a versão executável.

Execute o programa (não precisa instalar) e faça o login com sua conta do google, a mesma usada no seu aparelho. Ou crie outra, tanto faz.


Na tela principal, há um espaço para busca. Basta digitar o nome da aplicação e pressionar ENTER, do mesmo jeito que se faz no Google Play. No exemplo, eu busquei por 'Spock'.


Localizada a aplicação, clique no botão "download" correspondente. Pronto! O apk está no seu PC. Note o caminho, na barra de título, para saber onde busca-lo quando necessário.

Agora, precisamos descompactar o apk baixado. Para isso, usamos o programa apktool.
O apktool é um programa de terminal, escrito em java. Então, para usá-lo é necessário saber usar o terminal do windows e ter o java instalado. O apktool 2.x necessita do java 1.7 ou superior. Abra o terminal e digite

java -version

e veja se a versão é igual ou superior a 1.7. Se não for, atualize o java antes de prosseguir.
Estanto OK, baixe este script e salve-o num caminho conhecido. 
Depois, baixe o apktool.jar, procurando aqui pela versão mais recente. Renomeie o arquivo para apktool.jar  (na hora de 'salvar como' ou depois, tanto faz, mas não esqueça!) 

Abra o terminal, navegue até a pasta onde está o apktool e digite 

apktool

para ver se está OK. Ele deve retornar imprimindo como usá-lo.
OK! Estamos quase prontos. Procure o apk que foi baixado. Siga o caminho apontado na barra de título do Raccoon, entre na pasta 'apk_storage' e dentro dela irá encontrar a pasta da aplicação baixada. Dentro dela está o .apk que precisamos. Mova-o para a pasta onde o apktool foi baixado.

Descompactando o apk
No terminal, digite agora 

apktool d [nome]

onde [nome] é o nome do seu arquivo .apk. Se digitar as primeiras letras e apertar a tecla TAB, o windows deve preencher o resto. Aperte ENTER. No exemplo, eu fiz com o Google Chrome:


Agora, o apktool criou uma pasta contendo todos os arquivos do apk devidamente descompactados e desencriptados. 

Alterando o Androidmanifest.xml
Entre na pasta criada pelo apktool e abra o arquivo AndroidManifest.xml no bloco de notas (botão direito no arquivo, abrir com...).



Esqueça tudo o resto, menos a linha destacada em azul.
Isso é um TAG xml, ou seja, começa com o sinal de "<" e termina com ">". Esse tag, chamado 'manifest' é o que vamos alterar.
Aqui, supomos que precisamos inserir o atributo porque ela está faltando. Mas pode ser que já exista e, portanto, nesse caso basta alterar o valor.
Para inserir e ficar mais didático, vamos quebrar o tag em várias linhas:


Assim fica mais fácil identificar os vários atributos contidos no tag. Criamos então uma linha em branco (entre qualquer uma, desde que depois do '<' e antes do '>' e inserimos o atributo

android:installLocation="auto"

conforme ilustrado:

Agora, basta salvar o arquivo e fechar.

Aqui, cabem algumas explicações:
O atributo android:installLocation é um atributo opcional e pode ter três valores:
  • "auto" - Indica que a aplicação pode ser instalada na memória externa, mas não há preferência explícita de onde deve ser instalada. O sistema irá decidir onde instalar a aplicação com base em vários fatores. O usuário pode mover a aplicação entre essas duas memórias (o botão 'move to SD Card' irá ficar disponível).
  • "preferExternal" - A aplicação deve ser instalada preferencialmente na memória externa, mas o sistema não garante que seja realmente instalada nela. Por exemplo, se não houver memória externa ou se estiver sem espaço suficiente, a aplicação é instalada na interna. O usuário pode mover a aplicação entre essas duas memórias (o botão 'move to SD Card' irá ficar disponível).
  • "internalOnly" - Esse é o valor default, ou seja, se não for especificado, é o que vale. neste caso, a aplicação só pode ser instalada na memória interna e não pode ser movida para armazenamento externo.
Quando a aplicação é instalada em memória externa, vale o seguinte:
  • Não há efeito negativo sobre a performance, desde que a memória externa esteja montada no dispositivo.
  • A aplicação é salva na memória externa, mas dados privados do usuário, bases de dados, entre outras informações, são salvos na memória interna.
  • O container onde a aplicação é armazenada é encriptado com uma chave que somente o dispositivo que instalou conhece. Ou seja, tirar a memória externa e coloca-la num outro dispositivo não permitirá executar a aplicação nesse outro dispositivo
Vale uma atenção: quando o usuário conecta o dispositivo via USB e compartilha a memória externa, ela é desmontada do dispositivo, matando qualquer aplicação que estiver rodando a partir dela.

Portanto, não é recomendado instalar na memória externa:
  • Serviços
  • Alarmes
  • Wallpapers animados
  • Widgets
  • Gerenciadores de contas
  • Administradores de dispositivos

Hora de recompactar e assinar...
Estando o arquivo AndroidManifest.xml editado e salvo, usa-se o apktool novamente para gerar o .apk:

apktool b -o [nome.apk] [nome da pasta]

onde [nome.apk] é o nome que se quer dar à nova aplicação e  'nome da pasta' é o nome da pasta (naaaaaa, sério?) onde a aplicação foi descompactada.
 Agora, deve existir na pasta do apktool um arquivo nome.apk e basta assina-lo e estamos prontos para instalar no dispositivo.

Assinando e alinhando o apk zip...
Baixe o one click signer. Se o link estiver quebrado, procure no google. Descompacte-o na mesma pasta do apktool.
No terminal, chame-o pelo comando

one_click_signer.cmd

ele irá pedir o nome e caminho para o seu .apk
Rapidinho, ele irá criar um novo arquivo chamado signed-nome.apk e é esse que deve ser usado para instalar no dispositivo.


Instalando no dispositivo
Essa etapa é a mais simples. Mas antes de tudo, deve-se alterar a permissão para instalar aplicações fora do Google play. Para isso, deve-se entrar em Configurações - Segurança ligar a opção "Fontes desconhecidas":



Conecte seu dispositivo ao PC via USB (ou suba via dropbox, etc) e copie a aplicação signed-nome.apk para o dispositivo.

Estando lá, é necessário usar algum gerenciador de arquivos. Abra-o e navegue até a pasta onde foi gravado o signed-nome.apk. Clique nele e instale.

Pronto!!!
Entre nas configurações de aplicações e veja que o botão 'mover para o SD Card' está disponível.