我想有我的Gradle构建创建一个发布签名apk文件使用Gradle。

我不确定代码是否正确,或者我在做gradle构建时是否缺少一个参数?

这是build.gradle/build.gradle中的一些代码。节文件:

android {
    ...
    signingConfigs {
        release {
            storeFile(file("release.keystore"))
            storePassword("******")
            keyAlias("******")
            keyPassword("******")
        }
    }
}

Gradle构建成功完成,在我的build/apk文件夹中,我只看到…-release-unsigned.apk和…-debug-unaligned.apk文件。

对如何解决这个问题有什么建议吗?


当前回答

我设法解决它添加这段代码,并与gradle构建:

android {
    ...
    signingConfigs {
        release {
            storeFile file("release.keystore")
            storePassword "******"
            keyAlias "******"
            keyPassword "******"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

这将生成一个已签名的发布apk文件。

其他回答

使用git时使用Gradle自动应用程序签名

令人惊讶的是,有这么多复杂的方法可以做到这一点。这是我自己的方法,我试图坚持谷歌自己的建议。但是,他们的解释并不完全清楚,所以我将详细描述Linux的过程。


描述:

自动签名应用程序的默认谷歌指令 在构建过程中,不保留密码和签名文件 在你的应用程序开发(GIT)路径中,是相当模糊的。这里是 详细说明了如何做到这一点。

最初的假设:

你有一个名为“MyApp”的应用程序,在以下路径给出的目录中: $ HOME / / mydev / MyApp项目。但是,使用MyApp目录和 由GIT控制。

问题

我们显然不希望在任何地方有我们的签名或密码文件 GIT控制的目录,即使我们很会使用。gitignore等,它仍然太冒险,容易犯错误。因此,我们希望我们的密钥存储库和签名文件在外部。

解决方案

我们需要做三件事:

创建一个Android Studio使用的密码文件 创建签名密钥文件 编辑模块构建。Gradle文件使用(1)和(2)。

在本例中,我们将这两个文件命名为:

keystore.properties MyApp-release-key.jks

我们可以把这两个文件放在这里:

cd $HOME/projects/mydev/

(1)创建keystore密码文件

第一个文件包含明文密码;和(2)中释放密钥文件的路径。从填写这个开始,因为它将使下一步的复制粘贴操作更容易。

cd $HOME/projects/mydev/

编辑密钥存储库。属性,所以它的内容是:

storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation

这里唯一棘手的部分是myStoreFileLocation。这是从模块构建中看到的路径。Gradle文件。这通常意味着路径类似于:$HOME/projects/mydev/MyApp/app/build.gradle。为了指向myapp -release-key。jks 文件,我们需要在这里放的是:

. . / . . / . . / MyApp-release-key.jks

这里,我们还为键选择了“myapp”别名。然后最终文件应该是这样的:

storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myapp
storeFile=../../../MyApp-release-key.jks

(2)创建签名文件

第二个文件在创建签名密钥时自动生成。 如果你没有其他应用程序,这是你唯一的密钥库,然后创建文件:

cd $HOME/projects/mydev/
keytool -genkeypair -v -keystore MyApp-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias myapp

这将要求您输入两个密码和一堆信息。(与Android Studio相同。)现在复制/粘贴您之前选择的密码。

(3)编辑gradle模块。构建文件以使用上面的内容

以下部分需要出现在你的应用/模块的Gradle构建文件中。首先,在android{}块的外面和前面添加以下行。

//def keystorePropertiesFile = rootProject.file("$HOME/.android/keystore.properties")
def keystorePropertiesFile = rootProject.file("../../keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

然后,在android{}块中添加:

android {
    ...
    defaultConfig { ... }
    signingConfigs {
            release {
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
                storeFile file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']
            }
        }
    // Tell Gradle to sign your APK
    buildTypes {
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

现在从shell,你可以重建你的应用程序:

cd $HOME/projects/mydev/MyApp/app/
./gradlew clean build

这应该生成一个正确签名的应用程序,可以在谷歌播放中使用。


更新:2019-04-02

最新版本的keytool和一些东西告诉你,你应该使用一个基于PKCS12的keyfile,而不是我上面使用的原始/默认的keyfile。然后他们继续告诉你,你应该转换到新的开放PKCS12格式。然而,似乎Android开发工具还没有完全准备好,因为如果你这样做了,你会得到以下奇怪的错误:

com.android.ide.common.signing.KeytoolException: read key失败 “F:\XXX\XXX.”获取键失败:给定的最终块没有 适当的衬垫。如果在过程中使用了错误的密钥,就会出现这种问题 解密。

所以不要使用转换后的密钥!

@Destil的答案很好,如果你可以在所有项目中重用相同的配置。或者,Android Studio自带本地文件。可以使用的属性文件,但它应该是ide生成的,我找不到一种方法来扩展它从Android Studio。

这是@jonbo回答的一个变体。这个答案允许项目特定的设置,但它带来了一些开发人员的开销。具体来说,需要大量的样板文件来将signingConfigs定义移动到一个单独的文件中——特别是当您需要为多个项目这样做时,这是选择这个解决方案而不是Destil的主要原因。这可以通过包含线条在一定程度上得到缓解

apply plugin: 'com.android.application'

在凭证文件中,因为这将允许IDE完成。

最后,这里的大多数解决方案不允许在不提供语法上(如果不是语义上)有效的signingConfigs定义的情况下以调试模式构建项目(自动处理调试签名)。如果您不需要从给定的机器生成一个发布版本,那么这个额外的步骤可以被视为一个不必要的障碍。另一方面,它可以帮助在生产中运行调试构建的无知或懒惰的同事。

这个解决方案将允许调试构建而完全不用担心凭证,但是它将需要有效的凭证来生成发布构建,并且它只需要很少的样板文件。然而,作为一个缺点,它可能会鼓励其他人用真实的凭证替换虚拟值,并且没有办法防止这种情况。

// app/build.gradle
// Define this structure in signing.gradle to enable release builds.
ext.signing = [
        storeFilePath : 'path/to/keystore',
        storePassword : 'keystore password',
        keyAlias      : 'key alias',
        keyPassword   : 'key password',
]

if (file('signing.gradle').exists()) {
    apply from: 'signing.gradle'
}

android {
    ...
    signingConfigs {
        release {
            storeFile file(project.signing.storeFilePath)
            storePassword project.signing.storePassword
            keyAlias project.signing.keyAlias
            keyPassword project.signing.keyPassword
        }
    }
    buildTypes {
        debug { ... }
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

这将创建一个虚拟属性,纯粹用于生成语法上有效的构建文件。在调试构建阶段,分配给ext.signing属性的值是不相关的。要启用发布版本,请将ext.signing复制到signing中。Gradle并将虚拟值替换为有效凭证。

// signing.gradle
ext.signing = [
        storeFilePath : 'real/keystore',
        storePassword : 'real keystore password',
        keyAlias : 'real key alias',
        keyPassword : 'real key password',
]

当然,签名。gradle应该被VCS忽略。

我设法解决它添加这段代码,并与gradle构建:

android {
    ...
    signingConfigs {
        release {
            storeFile file("release.keystore")
            storePassword "******"
            keyAlias "******"
            keyPassword "******"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

这将生成一个已签名的发布apk文件。

如果您想避免在构建中硬编码您的密钥库和密码。gradle,你可以使用属性文件解释这里:处理签名配置与gradle

基本上:

1)创建一个myproject。属性文件在/home/[username]/。签名内容如下:

keystore=[path to]\release.keystore
keystore.password=*********
keyAlias=***********
keyPassword=********

2)创建gradle。属性文件(可能在你的项目目录的根目录)的内容:

MyProject.properties=/home/[username]/.signing/myproject.properties

3)在你的构建中参考它。这样Gradle:

    if(project.hasProperty("MyProject.properties")
        && new File(project.property("MyProject.properties")).exists()) {

    Properties props = new Properties()
    props.load(new FileInputStream(file(project.property("MyProject.properties"))))

    signingConfigs {
        release {
            storeFile file(props['keystore'])
            storePassword props['keystore.password']
            keyAlias props['keyAlias']
            keyPassword props['keyPassword']
        }
    }
}

现在是2019年,我需要用V1 (jar签名)或V2(完整APK签名)签署APK。我谷歌了“生成签名apk gradle”,它把我带到了这里。我把原来的解加到这里。

signingConfigs {
    release {
        ...
        v1SigningEnabled true
        v2SigningEnabled true
    }
}

我最初的问题:如何从构建开始使用V1 (Jar签名)或V2(完整的APK签名)。gradle文件