2011-11-07 13 views
37

Używając Anta, próbuję zbudować aplikację Android w trybie wydania do dystrybucji. Mój problem dotyczy procesu podpisywania. Utworzyłem magazyn kluczy i alias za pomocą Eclipse przy użyciu kreatora Eksportuj aplikację na Androida, a aplikacja jest poprawnie podpisana, jeśli wyeksportuje ją przez Eclipse. Kiedy staram się ukończyć ten sam proces poprzez Ant odwołać mój kluczy i alias w moim pliku build.properties:Podpisywanie Android za pomocą Anta

key.store=C:\\Users\\a512091\\.android\\release.keystore 
key.alias=application 
key.store.password=android 
key.alias.password=android 

Proces kompilacji jest udany i dostaję plik Application-release.apk. Naprawiłem ten plik APK z jarsignerem, a wszystkie pliki mają znaczniki "sm". To jest ogon wyjścia:

jar verified. 
Warning: 
This jar contains entries whose certificate chain is not validated. 

Kiedy próbuję zainstalować ten plik APK w emulatorze lub urządzeniu pojawia się następujący:

Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] 

Logcat pokazuje problemy z logowaniem na mój plik CSS oraz aktywów graficznych :

11-07 11:06:20.060: WARN/PackageParser(58): Exception reading assets/www/css/base.css in /data/app/vmdl48898.tmp 
11-07 11:06:20.060: WARN/PackageParser(58): java.lang.SecurityException: META-INF/XXXXX.SF has invalid digest for assets/www/res/droidhdpi/favorite_off.png in /data/app/vmdl48898.tmp 
11-07 11:06:20.060: WARN/PackageParser(58):  at java.util.jar.JarVerifier.verifyCertificate(JarVerifier.java:369) 
11-07 11:06:20.060: WARN/PackageParser(58):  at java.util.jar.JarVerifier.readCertificates(JarVerifier.java:272) 
11-07 11:06:20.060: WARN/PackageParser(58):  at java.util.jar.JarFile.getInputStream(JarFile.java:392) 
11-07 11:06:20.060: WARN/PackageParser(58):  at android.content.pm.PackageParser.loadCertificates(PackageParser.java:337) 
11-07 11:06:20.060: WARN/PackageParser(58):  at android.content.pm.PackageParser.collectCertificates(PackageParser.java:508) 
11-07 11:06:20.060: WARN/PackageParser(58):  at com.android.server.PackageManagerService.installPackageLI(PackageManagerService.java:5885) 
11-07 11:06:20.060: WARN/PackageParser(58):  at com.android.server.PackageManagerService.access$2100(PackageManagerService.java:134) 
11-07 11:06:20.060: WARN/PackageParser(58):  at com.android.server.PackageManagerService$5.run(PackageManagerService.java:4743) 
11-07 11:06:20.060: WARN/PackageParser(58):  at android.os.Handler.handleCallback(Handler.java:587) 
11-07 11:06:20.060: WARN/PackageParser(58):  at android.os.Handler.dispatchMessage(Handler.java:92) 
11-07 11:06:20.060: WARN/PackageParser(58):  at android.os.Looper.loop(Looper.java:123) 
11-07 11:06:20.060: WARN/PackageParser(58):  at android.os.HandlerThread.run(HandlerThread.java:60) 
11-07 11:06:20.069: ERROR/PackageParser(58): Package com.xxxxx.xxxxx has no certificates at entry assets/www/css/base.css; ignoring! 

Odpowiedz

49

Jeśli masz wersję Ant < 1.8.3 (ant -version) spróbuj tego podejścia do problemu z JDK 7 (na podstawie poprzedniej odpowiedzi):

  1. Dodaj signjarjdk7 do ANDROID_SDK \ tools \ ant \ build.xml

    <macrodef name="signjarjdk7"> 
        <attribute name="jar" /> 
        <attribute name="signedjar" /> 
        <attribute name="keystore" /> 
        <attribute name="storepass" /> 
        <attribute name="alias" /> 
        <attribute name="keypass" /> 
        <attribute name="verbose" /> 
        <sequential> 
         <exec executable="jarsigner" failonerror="true"> 
          <!-- Magic key, always verbose --> 
          <arg line="-verbose -digestalg SHA1 -sigalg MD5withRSA" /> 
          <arg line="-keystore @{keystore} -storepass @{storepass} -keypass @{keypass}" /> 
          <arg line="-signedjar &quot;@{signedjar}&quot;" /> 
          <arg line="&quot;@{jar}&quot; @{alias}" /> 
         </exec> 
        </sequential> 
    </macrodef> 
    
  2. wymienić 'signjar' do 'signjarjdk7' w 'release' celu w samej build.xml.

UWAGA: Musisz określić 'key.store.password' i 'key.alias.password' propeties dla projektu (w project.properties lub w local.properties).

UPDATE 1:

Jeśli urządzenie zostało zainstalowane Ant 1.8.3 (lub nowszy) masz lepsze rozwiązanie:

otwórz swój ANDROID_SDK \ tools \ ant \ build.xml i dodać dwa nowe parametry - sigalg i digestalg - w oryginale 'signjar' inwokacji:

<signjar 
    sigalg="MD5withRSA" 
    digestalg="SHA1" 
    jar="${out.packaged.file}" 
    signedjar="${out.unaligned.file}" 
    keystore="${key.store}" 
    storepass="${key.store.password}" 
    alias="${key.alias}" 
    keypass="${key.alias.password}" 
    verbose="${verbose}" /> 

UPDATE 2: wydaje ta odpowiedź jest przestarzała po „s ignjar "został zamieniony na" signapk "w najnowszej wersji narzędzi Android SDK.

+0

W jaki sposób należy uwzględnić atrybut "verbose"? Teraz flaga verbose jest zawsze ustawiona. –

+0

"verbose" wymaga jedynie łatwego zastąpienia oryginalnego celu "signjar". – FeelGood

+0

Czy możesz podać więcej informacji o swoim rozwiązaniu 1.8.3+. Jakie są te zmienne? Skąd czerpię ich wartości? – Guy

9

brzmi jak można używać JDK 7 (1.7.0), więc spróbuj dodać te opcje przy podpisywaniu z jarsigner:

-digestalg SHA1 -sigalg MD5withRSA 
+0

Tak używam JDK 7 więc próbowałem opcje i proces rejestracji zakończył idealnie. Dziękuję Ci! Zakładam, że te argumenty są również zgodne z JDK 6, czy mam rację? – sgimeno

+0

Złe jest to, że zadanie signjar w ANT nie obsługuje atrybutu "args", więc podpis musi zostać wykonany przy użyciu exec lub java, które jest mniej czyste, jak sądzę. – sgimeno

+0

Tak, te argumenty były również obecne w JDK 6 I liczyć. –

2

rozwiązanie długoterminowe jest plaster zadanie signjar Ant:

https://issues.apache.org/bugzilla/show_bug.cgi?id=52344

Nowe cechy dodano signjar ant 1,8.3, ale skrypt build Androida (od R19) nie został zmodyfikowany, aby je wykorzystać:

http://code.google.com/p/android/issues/detail?id=19567

W międzyczasie "presetdef" może dostarczyć rozwiązania:

<presetdef name="signjar"> 
    <signjar sigalg="MD5withRSA" digestalg="SHA1" /> 
</presetdef> 
+1

Przepraszamy za duplikat komentarza. Próbuję zwiększyć moje szanse na uzyskanie odpowiedzi. To wszystko jest dla mnie bardzo mylące, ponieważ na http://developer.android.com/tools/publishing/app-signing.html#signapp mówią, że używają '-sigalg SHA1withRSA -digestalg SHA1'. Dlaczego używamy MD5withRSA? –

+0

Sposób obejścia -sigalg = MD5withRSA określał domyślną wartość RSA dla jarsignera w Javie 6. To ustawienie domyślne zmieniło się na SHA256 z Oracle w Java 7, jednak nie było to obsługiwane w systemie Android. SHA1withRSA jest bezpieczniejszą opcją, która jest (podobno) obsługiwana na systemie Android i dlatego jest lepsza. –

0

Jeśli „re zatrzymany (jak ja) z wersji starszej niż 1.8.3 Ant i Java 7, tutaj jest obejście:

<exec executable="${java.bin.path}/jarsigner"> 
    <arg value="-signedjar"/> 
    <arg value="signed-${app.apk.name}"/> 
    <arg value="-keystore"/> 
    <arg value="my.keystore"/> 
    <arg value="-storepass"/> 
    <arg value="passwd"/> 
    <arg value="-sigalg"/> 
    <arg value="MD5withRSA"/> 
    <arg value="-digestalg"/> 
    <arg value="SHA1"/> 
    <arg value="${app.apk.name}"/> 
    <arg value="my_keystore"/> 
</exec> 

<!-- Where old version was: --> 

<signjar 
    alias="my_keystore" keystore="my.keystore" 
    storepass="passwd" 
    preservelastmodified="true" 
    signedjar="signed-${app.apk.name}"> 
    <path> 
    <fileset dir="." includes="${app.apk.name}" /> 
    </path> 
</signjar> 
6

Per Android developer documentation, należy umieścić te właściwości w ciągu t on ant.properties file:

$ cat ant.properties 
key.store=C:\\Users\\a512091\\.android\\release.keystore 
key.alias=application 
key.store.password=android 
key.alias.password=android 
1

Korzystanie Ubuntu 14.04 (Trusty Tahr) i Windows, stworzyć „.keystore” plik.

Ten plik musi zostać wygenerowany, co można wykonać za pomocą polecenia keytool dołączonego do środowiska Java. Zwykle można go znaleźć w "C: \ Program Files \ Java \ jre7 \ bin". Które również należy dodać do zmiennej PATH.

Przejdź do katalogu głównego projektu i użyj polecenia:

Generowanie pliku .keystore:

$ keytool -genkey -v -keystore key-name.keystore -alias alias-name -keyalg RSA -keysize 2048 -validity 10000 

Utwórz plik o nazwie ant.properties w folderze „Platformy/android /” ant.properties.

key.store=D:\\path\\to\\the\\project\\keyname.keystore 
key.alias=alias-name 

Utwórz plik build APK:

$ cordova build android --release 
Powiązane problemy