40

Is it possible to specify the location of a self created debug keystore when creating debug .apk's (<project-name>-debug.apk) with ant debug? I only see the possibility to specify the location of the release keystore.

I would like to share the debug keystore over multiple PC's without copying them over the the one that is placed in the '.android' directory. The debug keystore could for example reside within the source code repository. But I need a way to tell ant where to find the debug keystore.

Flow
  • 23,572
  • 15
  • 99
  • 156
Huupke
  • 1,158
  • 1
  • 13
  • 25

7 Answers7

20

You should be able to specify the keystore to use with these properties

key.store=/path/to/key.keystore
key.alias=alias
key.store.password=pass
key.alias.password=pass

Just pass the properties in to Ant.

[EDIT] From the docs at http://developer.android.com/guide/publishing/app-signing.html#setup

The Android build tools provide a debug signing mode that makes it easier for you to develop and debug your application, while still meeting the Android system requirement for signing your .apk. When using debug mode to build your app, the SDK tools invoke Keytool to automatically create a debug keystore and key. This debug key is then used to automatically sign the .apk, so you do not need to sign the package with your own key.

The SDK tools create the debug keystore/key with predetermined names/passwords:

  • Keystore name: "debug.keystore"
  • Keystore password: "android"
  • Key alias: "androiddebugkey"
  • Key password: "android"
  • CN: "CN=Android Debug,O=Android,C=US"

If necessary, you can change the location/name of the debug keystore/key or supply a custom debug keystore/key to use. However, any custom debug keystore/key must use the same keystore/key names and passwords as the default debug key (as described above). (To do so in Eclipse/ADT, go to Windows > Preferences > Android > Build.)

cweiske
  • 30,033
  • 14
  • 133
  • 194
codemonkey
  • 5,257
  • 2
  • 18
  • 16
  • 2
    it seems this doesn't work for debug but only for release. Are you sure this works for signing the debug apk? – Huupke Jan 30 '12 at 11:51
  • It is probably only possible to overwrite the keystore in the default location. For platform or release keys specifying the location is possible by properties mentioned above. – Huupke Feb 08 '12 at 12:49
  • 3
    Eclipse preferences are not used when building on command-line using ant which was my question. key.store is omitted when building for debug. – Huupke Feb 13 '12 at 07:42
  • Does this work for anyone with ant building for signed debug? – Guy Oct 16 '12 at 08:46
  • This approach doesn't work for "ant debug", but it for sure works for "ant release" – Nickolai Astashonok Jun 22 '14 at 13:16
11

As far as I can tell, in order to do this you need to override the "-do-debug" target. I'd like to know if there's a more elegant way, though. I added this to my build.xml

<property name="build.is.signing.debug" value="false"/>
<target name="-do-debug" depends="-set-debug-mode, -debug-obfuscation-check, -package, -post-package">
    <!-- only create apk if *not* a library project -->
    <do-only-if-not-library elseText="Library project: do not create apk..." >
        <sequential>
            <property name="out.unaligned.file" location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" />

            <!-- Signs the APK -->
            <echo>Signing final apk...</echo>
            <signjar
                    jar="${out.packaged.file}"
                    signedjar="${out.unaligned.file}"
                    keystore="${key.store}"
                    storepass="${key.store.password}"
                    alias="${key.alias}"
                    keypass="${key.alias.password}"
                    verbose="${verbose}" />

            <!-- Zip aligns the APK -->
            <zipalign-helper
                    in.package="${out.unaligned.file}"
                    out.package="${out.final.file}" />
            <echo>Debug Package: ${out.final.file}</echo>
        </sequential>
    </do-only-if-not-library>
    <record-build-info />
</target>
<import file="${sdk.dir}/tools/ant/build.xml" />
heathkit
  • 573
  • 5
  • 12
  • I'm not sure what's going wrong, but when running Ant using this method I'm getting a warning: "No -tsa or -tsacert is provided and this jar is not timestamped." When attempting to install the resulting APK, I get "Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]". Exporting through Eclipse appears to work, however. Any ideas? – Paul Lammertsma Jan 29 '14 at 11:14
  • Running `jarsigner` on the APK after running Ant indeed gives a SecurityException, so it appears that it doesn't get signed correctly. – Paul Lammertsma Jan 29 '14 at 11:17
  • It appears that the `build.is.signing.debug` property conflicts with this method, as `apkbuilder` already signs it using the debug keystore in your home directory. I managed to resolve this by overriding the `-setup` target and setting the property to false. – Paul Lammertsma Jan 29 '14 at 11:39
4
  • Create a new and empty folder within your Eclipse workspace.

  • Copy the file "debug.keystore" from its standard location (e.g. "c:/Users/YourAcount/.Android/" on Windows) into that new directory.

  • Configure Eclipse to use that new directory/file for all Debug APKs (Eclipse --> Window --> Preferences --> Android --> Build --> Custom Debug Keystore".

Harald Wilhelm
  • 6,656
  • 11
  • 67
  • 85
4

One easy method you can use as a work-around (which is especially nice in our CI system where many projects are built and where a soft touch is required when dealing with keystores), is to go ahead and run the debug build, use AAPT to remove the contents of the META-INF folder, and run jarsigner to sign it with your custom debug.keystore.

In pseudo-script, it looks like: # Normal Ant debug build ant debug

# Remove default debug signing
aapt remove YourDebugApp.apk META-INF/MANIFEST.MF
aapt remove YourDebugApp.apk META-INF/CERT.SF
aapt remove YourDebugApp.apk META-INF/CERT.RSA

# Use Jarsigner and the custom debug.keystore. 
# NOTE: This assumes you explicitly called out MD5withRSA as your signing algorithm 
# when you generated the key; drop the -sigalg tag if you did not.
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore -storepass android YourDebugApp.apk

# Verify signing
jarsigner -verify YourDebugApp.apk
4

You can remove the signature of the final apk and sign it again. It is just a debug build so the zipalign can be avoided (at least I have no problems in my build).

Copy your keystore to a file debug.keystore in the project and add the following in ant.properties

debug.key.store.password=android
debug.key.alias.password=android
debug.key.store=../debug.keystore
debug.key.alias=androiddebugkey

And add the following in your build.xml

<target name="-post-build" if="${build.is.packaging.debug}">
    <!-- Remove the signature of the debug build, and sign it again with our own debug keystore -->
    <delete dir="tmp" includeemptydirs="true" failonerror="false" />
    <mkdir dir="tmp" />
    <unzip src="${out.final.file}" dest="tmp" />
    <delete dir="tmp/META-INF" includeemptydirs="true" verbose="true" failonerror="true" />
    <delete file="${out.final.file}" failonerror="true" />
    <zip destfile="${out.final.file}" basedir="tmp" />
    <delete dir="tmp" includeemptydirs="true" failonerror="false" /> 

    <echo level="info">Signing final DEBUG apk with a common signature...
        signapk
            input="${out.final.file}"
            output="${out.packaged.file}"
            keystore="${debug.key.store}"
            storepass="${debug.key.store.password}"
            alias="${debug.key.alias}"
            keypass="${debug.key.alias.password}"
    </echo>

    <signapk
        input="${out.final.file}"
        output="${out.packaged.file}"
        keystore="${debug.key.store}"
        storepass="${debug.key.store.password}"
        alias="${debug.key.alias}"
        keypass="${debug.key.alias.password}"/>

    <delete file="${out.final.file}" failonerror="true" />
    <move file="${out.packaged.file}" tofile="${out.final.file}" failonerror="true" />

</target>
Ignacio Tomas Crespo
  • 3,401
  • 1
  • 20
  • 13
0

As far as I've seen so far no existing solution works with the latest ant version.

The only primitive way of doing it is to replace the default debug.keystore its in default folder.

The default location is the .android folder. Usually at C:\Users\USER_NAME.android On windows you can get to it using %USERPROFILE%.android.

What I did is create a powershell script to backup the default file, copy keystore file to the default location, build the signed debug apk, delete my keystore file, restore original file.

Let me know if you need more information here.

Guy
  • 5,370
  • 6
  • 25
  • 30
0

I found the another solution..

Add the following in ${PROJECT_HOME}/custom_rules.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules">
    <!-- @Override -->
    <target name="-set-debug-mode" depends="-setup">
        <!-- record the current build target -->
        <property name="build.target" value="debug" />

        <if>
            <condition>
                <and>
                    <istrue value="${project.is.testapp}" />
                    <istrue value="${emma.enabled}" />
                </and>
            </condition>
            <then>
                <property name="build.is.instrumented" value="true" />
            </then>
            <else>
                <property name="build.is.instrumented" value="false" />
            </else>
        </if>

        <!-- whether the build is a debug build. always set. -->
        <property name="build.is.packaging.debug" value="true" />

        <!-- signing mode: debug -->
        <property name="build.is.signing.debug" value="false" />

        <!-- Renderscript optimization level: none -->
        <property name="renderscript.opt.level" value="${renderscript.debug.opt.level}" />

    </target>

    <!-- @Override -->
    <!-- Builds debug output package -->
    <target name="-do-debug" depends="-set-debug-mode, -debug-obfuscation-check, -package, -post-package">
        <property name="out.unsigned.file" location="${out.absolute.dir}/${ant.project.name}-debug-unsigned.apk"/>
        <move file="${out.packaged.file}" tofile="${out.unsigned.file}"/>
        <property name="out.unaligned.file" location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" />

        <!-- Signs the APK -->
        <echo level="info">Signing final apk...</echo>
        <signapk
            input="${out.unsigned.file}"
            output="${out.unaligned.file}"
            keystore="${out.absolute.dir}/../debug.keystore" <!-- your debug.keystore path -->
            storepass="android"
            alias="androiddebugkey"
            keypass="android"/>

        <!-- only create apk if *not* a library project -->
        <do-only-if-not-library elseText="Library project: do not create apk..." >
            <sequential>
                <zipalign-helper in.package="${out.unaligned.file}" out.package="${out.final.file}" />
                <echo level="info">Debug Package: ${out.final.file}</echo>
            </sequential>
        </do-only-if-not-library>
        <record-build-info />
    </target>

</project>
Sinhyeok
  • 46
  • 4