segunda-feira, 6 de agosto de 2012

Unity3D falha ao assinar APK com JDK 1.7

O Erro e o Porquê


Unable to install APK!
    pkg: /data/local/tmp/Package.apk


Recentemente fui publicar um apk feito na unity na play store e me deparei com um terrível erro na hora de testar meu aplicativo no celular: "aplicativo não instalado". Mas estava tudo correto, mas não instalava que dirá submeter para o play store.
 
Com um pouco de pesquisa encontrei que o erro era com a Unity e o JDK 1.7, já que projetos no Eclipse exportavam corretamente aplicações assinadas. Provavelmente a Unity 3D atual não especifica o algoritmo de assinatura, já que o algoritmo padrão do JDK 1.7 foi modificado. Para isso é necessário especificar o algoritmo para o jarsigner usando as cláusulas (-sigalg e -digestalg). 

Engraçado que usando o JDK 1.6 a Unity consegue assinar corretamente, mas não consegue usar o keytool que é reponsável por criar as chaves e acessar as chaves cadastradas.

Corrigindo o erro

Embora ignorando a Unity e assinando as aplicações manualmente, o jarsigner não conseguia fazer a coisa direito e na hora de verificar a assinatura sempre problemas ocorriam.

Reverti o JDK para 1.6 e assinei manualmente. Para isso os seguintes passos serão suficientes:

Receita:

Instale o JDK 1.6, não é necessário remover o JDK 1.7, mas lembre-se de usar os executáveis da pasta bin do JDK1.6!

Crie seu keystore e a chave a ser usada.

Faça um build pela Unity3D e use a assinatura padrão: "unsigned(debug)".



Use o 7zip para remover a assinatura do APK gerado, (abra o apk usando o 7zFM), para isso remova a pasta META-INF de dentro do APK e feche o 7zFM ao terminar.

Se quiser verificar se o APK é só usar o comenado no console:

jarsigner -verify my_signed.apk

Agora, é só assinar a aplicação!

jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name

Onde esse alias_name é nome do alias que você deu para sua chave inserida no keystore.

Uma vez assinado, verifique para confirmar

jarsigner -verify my_signed.apk

Após estar tudo ok, use o zipalign para otimizar o uso de memória do seu apk.
zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk
Pronto, sua aplicação está finalmente assinada corretamente e otimizada, pronta para ser submetida!
Mais detalhes aqui.

5 comentários:

  1. Ola Fernando, parabéns pelo blog.

    cara não entendi como faz para assinar a aplicação depois do ajuste. Onde eu coloco com (jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name) ?.

    obrigado por compartilhar seus conhecimentos! abraço

    ResponderExcluir
    Respostas
    1. Cara, esse post é de 6 de agosto de 2012, é provável que a essa altura já tenha sido corrigido esse bug.
      Tente primeiro atualizar a Unity e o Java para a última versão, se o erro prosseguir, então resta seguir o tutorial.

      Esse comando você vai utilizá-lo no prompt de comando do Windows, ou no shell de alguma distro linux ou no shell do MAC.

      Excluir
    2. obrigado pela resposta. Esse bug ainda ronda a galera que usa o unity, pois muitos ainda não migraram para o unity 4 por questoes de compatibilidade. valeu. abraço

      Excluir
  2. Ops! nao deu! fiz uma primeira tentativa e nao foi na segunda aparece ( Enter Passphrase for keystore:) digito e nao aparece no terminal ( no Mac os) . oque sera que esta acontecendo? abraço

    ResponderExcluir
    Respostas
    1. A senha digita realmente não é para aparecer ;D
      a primeira senha é a do keystore e a segunda é a da assinatura para a aplicação.

      Excluir