garrik
garrik

Reputation: 93

Generated APK is not signed if signature v2 is selected

I am trying to generate a signed APK for my app and it works if I only use signature V1. When I use signature V2 and then check apk with keytool, the output is:

keytool -list -printcert -jarfile app-release.apk
Not a signed jar file

Here is the build.gradle:

def getProps(path) {
    Properties props = new Properties()
    props.load(project.rootProject.file(path).newDataInputStream())
    return props
}

android {
    ...
    signingConfigs {
        debug {
            try {
                Properties props = getProps('./local.properties')
                storeFile file(props.getProperty('DEBUG_STORE_FILE', ''))
                keyAlias props.getProperty('DEBUG_KEY_ALIAS', '')
                keyPassword props.getProperty('DEBUG_STORE_PASSWORD', '')
                storePassword props.getProperty('DEBUG_STORE_PASSWORD', '')
                v1SigningEnabled true
                v2SigningEnabled false // enabling this generates unsigned apk
            }
            catch (ex) {
                throw new InvalidUserDataException("You should define RELEASE_STORE_FILE, RELEASE_KEY_ALIAS, RELEASE_STORE_PASSWORD in local.properties.")
            }
        }
        release {
            try {
                Properties props = getProps('./local.properties')
                storeFile file(props.getProperty('RELEASE_STORE_FILE', ''))
                keyAlias props.getProperty('RELEASE_KEY_ALIAS', '')
                keyPassword props.getProperty('RELEASE_STORE_PASSWORD', '')
                storePassword props.getProperty('RELEASE_STORE_PASSWORD', '')
                v1SigningEnabled true
                v2SigningEnabled false // enabling this generates unsigned apk
            }
            catch (ex) {
                throw new InvalidUserDataException("You should define RELEASE_STORE_FILE, RELEASE_KEY_ALIAS, RELEASE_STORE_PASSWORD in local.properties.")
            }
        }
    }

    defaultConfig {
        ...
        // Only productionRelease flavour uses signingConfigs.release;
        // other flavours(i.e. productionDebug, developmentDebug, developmentRelease)
        // use signingConfigs.debug
        // https://stackoverflow.com/questions/30898611/gradle-signing-flavors-with-different-keys-on-android
        signingConfig signingConfigs.release
    }
    buildTypes {
        release {
            ...
        }
        debug {
            ...
            signingConfig signingConfigs.debug
        }
    }
    // Dimensions: environment can be one of [development, production]
    flavorDimensions "environment"
    productFlavors {
        development {
            ...
            signingConfig signingConfigs.debug
            ...
        }
        production {
            dimension "environment"
        }
    }
    ...
}

I also created a new Android project from scratch and it has the same issue.

Note that I have another Android project which can produce a signed APK selecting both V1 and V2.

Why adding signature V2 is causing the generation of an unsigned APK?

Upvotes: 7

Views: 4364

Answers (2)

Shawlaw
Shawlaw

Reputation: 568

It's a bug from Android-Gradle-Plugin(AGP) when its version is below 4.0.0.

Here is the official description.

So there are two solutions:

  1. Keep your minSdkVersion to 23 or lower, like Euporie's answer

  2. Upgrade your AGP to 4.0.0 or higher.

    But please keep in mind that upgrading AGP usually need to upgrade buildToolsVersion and Gradle (in gradle-wrapper.properties if you are using gradleWrapper), sometimes even to upgrade JDK, synchronously.

    You can check AGP-Gradle-Compatibility and Gradle-JDK-Compatibility for detail version requirements.

Upvotes: 1

Euporie
Euporie

Reputation: 1986

Signature v2 was introduced in Android 7.0 (24), so when your minSdkVersion is 24 or higher, enable both v1 and v2 like this:

signingConfigs {
        debug {
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }

the signed apk will not have v1, it just signed with v2. This can be verified by apksigner like this:

java -jar apksigner.jar verify -v your-signed-apkfile.apk

enter image description here

Otherwise, keytool can not identify signature v2, so it prompt Not a signed jar file. And the signed apk with only signature v2 is also an available apk, it just can be installed on Android 7.0 or higher.

If you want signed with both v1 and v2, you should modify minSdkVersion to 23 or lower.

Hope it helps.

Upvotes: 11

Related Questions