我想有我的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文件。

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


当前回答

如果您已经拥有密钥存储库文件,那么只需向构建命令中添加一些参数即可:

./gradlew assembleRelease \
 -Pandroid.injected.signing.store.file=$KEYFILE \
 -Pandroid.injected.signing.store.password=$STORE_PASSWORD \
 -Pandroid.injected.signing.key.alias=$KEY_ALIAS \
 -Pandroid.injected.signing.key.password=$KEY_PASSWORD

不需要对Android项目进行永久性更改。

来源:http://www.tinmith.net/wayne/blog/2014/08/gradle-sign-command-line.htm

其他回答

这是对user672009的回复,也是对sdqali的帖子的补充(他的代码会在IDE的“Run”按钮构建调试版本时崩溃):

您可以使用以下代码:

final Console console = System.console();
if (console != null) {

    // Building from console 
    signingConfigs {
        release {
            storeFile file(console.readLine("Enter keystore path: "))
            storePassword console.readLine("Enter keystore password: ")
            keyAlias console.readLine("Enter alias key: ")
            keyPassword console.readLine("Enter key password: ")
        }
    }

} else {

    // Building from IDE's "Run" button
    signingConfigs {
        release {

        }
    }

}

比之前的答案更简单的方法:

把它放到~/.gradle/gradle.properties中

RELEASE_STORE_FILE={path to your keystore}
RELEASE_STORE_PASSWORD=*****
RELEASE_KEY_ALIAS=*****
RELEASE_KEY_PASSWORD=*****

修改你的应用/构建。Gradle,并将其添加到android{代码块:

...    
signingConfigs {

   release {
       storeFile file(RELEASE_STORE_FILE)
       storePassword RELEASE_STORE_PASSWORD
       keyAlias RELEASE_KEY_ALIAS
       keyPassword RELEASE_KEY_PASSWORD

       // Optional, specify signing versions used
       v1SigningEnabled true
       v2SigningEnabled true
   }
}

buildTypes {
        release {
            signingConfig signingConfigs.release
        }
}
....

然后你可以运行gradle assemblerrelease


另请参阅signingConfigs Gradle DSL的参考

使用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.”获取键失败:给定的最终块没有 适当的衬垫。如果在过程中使用了错误的密钥,就会出现这种问题 解密。

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

这是解决同一问题的另一种方法。由于不建议在源代码中存储任何类型的凭据,我们决定在一个单独的属性文件中设置密钥存储和密钥别名的密码,如下所示:

key.store.password=[STORE PASSWORD]
key.alias.password=[KEY PASSWORD]

如果使用git,可以创建一个名为secure.properties的文本文件。您应该确保从存储库中排除它(如果使用git,则将其添加到.gitignore文件中)。然后,您需要创建一个签名配置,就像其他一些答案所指出的那样。唯一的区别是如何加载凭据:

android {
    ...
    signingConfigs {
        ...
        release {
            storeFile file('[PATH TO]/your_keystore_file.jks')
            keyAlias "your_key_alias"

            File propsFile = file("[PATH TO]/secure.properties");
            if (propsFile.exists()) {
                Properties props = new Properties();
                props.load(new FileInputStream(propsFile))
                storePassword props.getProperty('key.store.password')
                keyPassword props.getProperty('key.alias.password')
            }
        }
        ...
    }

    buildTypes {
        ...
        release {
            signingConfig signingConfigs.release
            runProguard true
            proguardFile file('proguard-rules.txt')
        }
        ...
    }
}

永远不要忘记手动将signingConfig分配给发行版构建类型(出于某些原因,我有时假设它将被自动使用)。此外,启用proguard并不是强制性的,但建议这样做。

与使用环境变量或请求用户输入相比,我们更喜欢这种方法,因为它可以从IDE中完成,通过切换到release构建类型并运行应用程序,而不必使用命令行。

现在几乎所有的平台都提供了某种密匙环,所以没有理由留下明文密码。

我提出了一个简单的解决方案,使用Python密匙环模块(主要是配套的控制台脚本密匙环)和Groovy ['do', 'something'].execute()特性的最小包装:

def execOutput= { args ->
    def proc = args.execute()
    proc.waitFor()
    def stdout = proc.in.text
    return stdout.trim()
}

使用这个函数,signingConfigs部分变成:

signingConfigs {
    release {
        storeFile file("android.keystore")
        storePassword execOutput(["keyring", "get", "google-play", storeFile.name])
        keyAlias "com.example.app"
        keyPassword execOutput(["keyring", "get", "google-play", keyAlias])
    }
}

在运行gradle assemblerrelease之前,你必须在你的keyring中设置密码,只有一次:

$ keyring set google-play android.keystore # will be prompted for the passwords
$ keyring set google-play com.example.app

释放快乐!