2011-11-07 122 views
37

使用Ant,我試圖在發佈模式下構建Android應用程序以進行分發。我的問題是在簽名過程中。我使用導出Android應用程序嚮導通過Eclipse創建了一個密鑰倉庫和別名,如果通過Eclipse導出應用程序,它的簽名是正確的。當我嘗試完成通過Ant同一過程中,我引用我的密鑰庫和別名在我的build.properties文件:使用Ant與Android簽署

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

構建過程是成功的,我得到一個應用程序release.apk文件。我非常喜歡這個APK與jarsigner,所有文件都有「sm」標籤。這是輸出的尾巴:

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

當我嘗試這個APK安裝到仿真器或設備,我得到以下幾點:

Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] 

logcat的顯示在我的CSS文件和圖像資源簽約問題:

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! 

回答

49

如果你有螞蟻版本< 1.8.3(ant -version)嘗試這種方法與JDK 7的發佈(基於以前的答案):

  1. 添加signjarjdk7到ANDROID_SDK \工具\螞蟻\ 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. 在相同的build.xml替換'signjar''signjarjdk7''release'目標。

注意:您必須定義'key.store.password''key.alias.password'化子性質爲您的項目(在project.properties或local.properties)。

更新1:

如果您已經安裝了Ant 1.8.3(或更新版本),你有一個更好的解決方案:

打開ANDROID_SDK \工具\螞蟻\ build.xml文件,並添加了兩個新參數 - sigalg和digestalg - 在原來的 '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}" /> 

更新2: 看來這答案的後棄用ignjar'在最新版本的Android SDK工具中被替換爲'signapk'。

+0

應該如何考慮'verbose'屬性?現在,詳細標誌總是被設置。 –

+0

「詳細」只需要輕鬆替換原始的'signjar'目標。 – FeelGood

+0

您可以提供1.8.3+解決方案的更多信息。這些變量是什麼?我從哪裏得到他們的價值? – Guy

9

聽起來你可能會使用JDK 7(1.7.0),因此嘗試將這些選項與的jarsigner簽名時:

-digestalg SHA1 -sigalg MD5withRSA 
+0

是我使用的是JDK 7,所以我想你的選項和標誌過程完成完美。謝謝!我認爲這個參數也與JDK 6兼容,對嗎? – sgimeno

+0

不好的一面是ANT中的signjar任務不支持'args'屬性,所以簽名必須用exec或java任務來完成,我認爲這樣做不那麼幹淨。 – sgimeno

+0

是的,我認爲這些論據也出現在JDK 6中。 –

2

的長期解決方案是修補Ant的signjar任務:加入

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

新屬性的螞蟻1.8至signjar。3,但Android的構建腳本(如R19)的尚未被修改,以利用他們:

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

在此期間, 「presetdef」 可以提供一個解決方法:

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

對不起,重複的評論。試圖增加我得到答覆的機率。這對我來說非常混亂,因爲他們說他們使用'-sigalg SHA1withRSA -digestalg SHA1'來訪問http://developer.android.com/tools/publishing/app-signing.html#signapp。爲什麼我們使用MD5withRSA? –

+0

解決方法-sigalg = MD5withRSA指定了Java 6中jarsigner的RSA默認值。此默認值在Java 7中更改爲SHA256withRSA,但是,Android不支持此默認值。 SHA1withRSA是Android上顯然支持的更安全的選項,因此更可取。 –

0

如果您「再堅持(像我一樣)使用Ant版本1.8.3比和Java 7歲以上的,這裏有一個解決方法:

<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

Android developer documentation,你應該把t的範圍內,這些特性他的ant.properties文件:

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

使用Ubuntu 14.04(忠實的塔爾羊)和Windows,創建「的.keystore」文件。

需要生成這個文件,這可以通過Java附帶的keytool命令來完成。它通常可以在'C:\ Program Files \ Java \ jre7 \ bin'中找到。還必須將其添加到PATH變量中。

轉到你的項目的根目錄,使用這個命令:

生成的.keystore文件:

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

創建一個名爲文件夾中的文件ant.properties「平臺/安卓/」 ant.properties。

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

創建生成APK文件:

$ cordova build android --release