2011-11-07 15 views
37

Utilizzando Ant, sto cercando di creare un'applicazione Android in modalità di rilascio per la distribuzione. Il mio problema è al processo di firma. Ho creato un keystore e un alias tramite Eclipse utilizzando la procedura guidata Esporta applicazione Android e l'app è firmata correttamente se esportata tramite Eclipse. Quando provo a completare lo stesso processo tramite Ant riferisco mia keystore e alias nel mio file build.properties:Registrazione tramite Android con Ant

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

Il processo di creazione è successo e ho un file di Application-release.apk. Ho bloccato questo APK con jarsigner e tutti i file hanno tag "sm". Questa è la coda di uscita:

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

Quando provo ad installare questo APK in un emulatore o un dispositivo ottengo il seguente:

Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] 

Logcat mostra problemi di firma sul mio file CSS e risorse di immagini :

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! 

risposta

49

Se si dispone di versione 1.8.3 Ant < (ant -version) provare questo approccio per il problema con JDK 7 (in base alla risposta precedente):

  1. Aggiungi signjarjdk7 a ANDROID_SDK \ Tools \ formica \ 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. Sostituire 'signjar' a 'signjarjdk7' in 'release' destinazione nello stesso build.xml.

NOTA: È necessario definire 'key.store.password' e 'key.alias.password' propeties per il vostro progetto (in project.properties o in local.properties).

UPDATE 1:

Se il tuo hanno installato 1.8.3 Ant (o successivo) si dispone di una soluzione migliore:

Aprire l'ANDROID_SDK \ tools \ formica \ build.xml e aggiungere due nuovi parametri - sigalg e digestalg - nell'invocazione originale 'signjar':

<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: sembra questa risposta è deprecato dopo 's ignjar 'è stato sostituito in' signapk 'nell'ultima versione degli strumenti di Android SDK.

+0

Come deve essere preso in considerazione l'attributo 'verbose'? Ora il flag verbose è sempre impostato. –

+0

"verbose" deve solo sostituire facilmente la destinazione "signjar" originale. – FeelGood

+0

Puoi fornire ulteriori informazioni per la tua soluzione 1.8.3+. Quali sono queste variabili? Da dove ottengo i loro valori? – Guy

9

suona come si può utilizzare JDK 7 (1.7.0) in modo tenta di aggiungere queste opzioni al momento della firma con jarsigner:

-digestalg SHA1 -sigalg MD5withRSA 
+0

Sì sto utilizzando JDK 7 così ho provato le opzioni e processo di iscrizione finito perfettamente. Grazie! Presumo che questi argomenti siano anche compatibili con JDK 6, ho ragione? – sgimeno

+0

La cosa brutta è che l'attività signjar in ANT non supporta un attributo 'args' quindi la firma deve essere eseguita con un task exec o java che è meno pulito, credo. – sgimeno

+0

Sì, questi argomenti erano presenti anche in JDK 6. –

2

La soluzione a lungo termine è quello di rattoppare compito signjar di Ant:

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

I nuovi attributi sono stati aggiunti a signjar in Ant 1.8.3, ma script di build di Android (come di R19) non è ancora stata modificata per il loro impiego:

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

Nel frattempo, "presetdef" può fornire una soluzione:

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

Ci scusiamo per il commento duplicato. Cercando di aumentare le mie probabilità di ottenere una risposta. Questo mi confonde molto perché su http://developer.android.com/tools/publishing/app-signing.html#signapp si dice di usare '-sigalg SHA1withRSA -digestalg SHA1'. Perché stiamo usando MD5 conRSA? –

+0

La soluzione alternativa -sigalg = MD5 conRSA stava specificando qual era il valore predefinito di RSA per jarsigner in Java 6. Questo valore predefinito è stato modificato in SHA256 conRSA in Java 7, tuttavia, questo non era supportato su Android. SHA1withRSA è un'opzione più sicura che è (apparentemente) supportata su Android, quindi è preferibile. –

0

Se 're bloccato (come me) con una versione di Ant di età superiore a 1.8.3 e Java 7, ecco una soluzione:

<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, si dovrebbe mettere queste proprietà nel t egli ant.properties di file:

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

Utilizzando Ubuntu 14.04 (Trusty Tahr) e Windows, creare un file “.keystore”.

Questo file deve essere generato, operazione che può essere eseguita con il comando keytool fornito con Java. In genere può essere trovato in "C: \ Programmi \ Java \ jre7 \ bin". Che deve anche essere aggiunto alla variabile PATH.

andare alla radice del vostro progetto e utilizzare questo comando:

Generazione di un file .keystore:

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

Creare un file chiamato ant.properties nella cartella “piattaforme/android /” ant.properties.

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

Creare il file APK costruzione:

$ cordova build android --release