Bob*_*sky 138 android code-signing gradle android-studio
我正在尝试设置签名过程,以便密钥库密码和密钥密码不会存储在项目的build.gradle文件中.
目前我在以下方面有build.gradle:
android {
...
signingConfigs {
release {
storeFile file("my.keystore")
storePassword "store_password"
keyAlias "my_key_alias"
keyPassword "key_password"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Run Code Online (Sandbox Code Playgroud)
它的工作原理完全没有问题,但我不能把值的storePassword,而且keyPassword在我的仓库.我宁愿不把storeFile和keyAlias有两种.
有没有办法改变build.gradle它,以便它从某些外部源获取密码(如仅存在于我的计算机上的文件)?
当然,更改的内容build.gradle应该可以在任何其他计算机上使用(即使计算机无法访问密码).
我正在使用Android Studio和Mac OS X Maverics,如果它确实重要.
Sco*_*rta 112
关于Groovy的好处是你可以自由地混合使用Java代码,而且使用密钥/值文件很容易阅读java.util.Properties.也许使用惯用的Groovy更简单,但Java仍然非常简单.
创建一个keystore.properties文件(在本例中,在项目的根目录旁边settings.gradle,尽管你可以把它放在任何你喜欢的地方:
storePassword=...
keyPassword=...
keyAlias=...
storeFile=...
Run Code Online (Sandbox Code Playgroud)
将此添加到您的build.gradle:
allprojects {
afterEvaluate { project ->
def propsFile = rootProject.file('keystore.properties')
def configName = 'release'
if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
android.signingConfigs[configName].storeFile = file(props['storeFile'])
android.signingConfigs[configName].storePassword = props['storePassword']
android.signingConfigs[configName].keyAlias = props['keyAlias']
android.signingConfigs[configName].keyPassword = props['keyPassword']
}
}
}
Run Code Online (Sandbox Code Playgroud)
Cur*_*vus 93
或者,如果您想以更类似于自动生成的gradle代码的方式应用Scott Barta的答案,则可以keystore.properties在项目根文件夹中创建一个文件:
storePassword=my.keystore
keyPassword=key_password
keyAlias=my_key_alias
storeFile=store_file
Run Code Online (Sandbox Code Playgroud)
并将您的gradle代码修改为:
// Load keystore
def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
...
android{
...
signingConfigs {
release {
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
您可以将此属性文件存储在模块的根目录中,在这种情况下只需省略rootProject,您还可以修改此代码,以便为不同的密钥库和密钥别名提供多组属性.
Dan*_*ich 29
最简单的方法是创建一个~/.gradle/gradle.properties文件.
ANDROID_STORE_PASSWORD=hunter2
ANDROID_KEY_PASSWORD=hunter2
Run Code Online (Sandbox Code Playgroud)
然后你的build.gradle文件看起来像这样:
android {
signingConfigs {
release {
storeFile file('yourfile.keystore')
storePassword ANDROID_STORE_PASSWORD
keyAlias 'youralias'
keyPassword ANDROID_KEY_PASSWORD
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jar*_*ows 21
阅读几个链接后:
http://blog.macromates.com/2006/keychain-access-from-shell/ http://www.thoughtworks.com/es/insights/blog/signing-open-source-android-apps-without-disclosing-密码
由于您使用的是Mac OSX,因此可以使用Keychain Access来存储密码.

然后在你的gradle脚本中:
/* Get password from Mac OSX Keychain */
def getPassword(String currentUser, String keyChain) {
def stdout = new ByteArrayOutputStream()
def stderr = new ByteArrayOutputStream()
exec {
commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-gl', keyChain
standardOutput = stdout
errorOutput = stderr
ignoreExitValue true
}
//noinspection GroovyAssignabilityCheck
(stderr.toString().trim() =~ /password: '(.*)'/)[0][1]
}
Run Code Online (Sandbox Code Playgroud)
使用这样:
getPassword(currentUser,"Android_Store_Password")
/* Plugins */
apply plugin: 'com.android.application'
/* Variables */
ext.currentUser = System.getenv("USER")
ext.userHome = System.getProperty("user.home")
ext.keystorePath = 'KEY_STORE_PATH'
/* Signing Configs */
android {
signingConfigs {
release {
storeFile file(userHome + keystorePath + project.name)
storePassword getPassword(currentUser, "ANDROID_STORE_PASSWORD")
keyAlias 'jaredburrows'
keyPassword getPassword(currentUser, "ANDROID_KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mad*_*uja 17
我就是这样做的.使用环境变量
signingConfigs {
release {
storeFile file(System.getenv("KEYSTORE"))
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD")
}
Run Code Online (Sandbox Code Playgroud)
接受的答案使用文件来控制用于对驻留在项目的同一根文件夹中的APK进行签名的密钥库.当我们使用像Git这样的vcs时,当我们忘记将属性文件添加到忽略列表时可能会是一件坏事.因为我们会向全世界披露我们的密码.问题仍然存在.
而是在我们的项目中的同一目录中创建属性文件,我们应该在外面.我们使用gradle.properties文件在外面创建它.
这里的步骤:
1.在根项目上编辑或创建gradle.properties并添加以下代码,记得用自己的代码编辑路径:
AndroidProject.signing=/your/path/androidproject.properties
Run Code Online (Sandbox Code Playgroud)
2.创建androidproject.properties中/你/路径/和下面的代码添加到它,不要忘了/your/path/to/android.keystore改变您的密钥库的路径:
STORE_FILE=/your/path/to/android.keystore
STORE_PASSWORD=yourstorepassword
KEY_ALIAS=yourkeyalias
KEY_PASSWORD=yourkeypassword
Run Code Online (Sandbox Code Playgroud)
3.在你的app模块build.gradle(不是你的项目root build.gradle)中添加以下代码(如果不存在)或调整它:
signingConfigs {
release
}
buildTypes {
debug {
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
Run Code Online (Sandbox Code Playgroud)
4.在步骤3中的代码下面添加以下代码:
if (project.hasProperty("AndroidProject.signing")
&& new File(project.property("AndroidProject.signing").toString()).exists()) {
def Properties props = new Properties()
def propFile = new File(project.property("AndroidProject.signing").toString())
if(propFile.canRead()) {
props.load(new FileInputStream(propFile))
if (props!=null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
} else {
println 'androidproject.properties found but some entries are missing'
android.buildTypes.release.signingConfig = null
}
} else {
println 'androidproject.properties file not found'
android.buildTypes.release.signingConfig = null
}
}
Run Code Online (Sandbox Code Playgroud)
该代码将搜索AndroidProject.signing物业gradle.properties从第1步.如果找到该属性,它会将属性值转换为指向我们在步骤2中创建的androidproject.properties的文件路径.然后,它的所有属性值将用作build.gradle的签名配置.
现在我们不必再担心暴露我们的密钥库密码的风险.
阅读更多Signing Android apk,而无需在build.gradle中放置密钥库信息
对于那些希望将他们的凭据放在外部JSON文件中并从gradle中读取的人来说,这就是我所做的:
MY_PROJECT/credentials.json:
{
"android": {
"storeFile": "/path/to/acuity.jks",
"storePassword": "your_store_password",
"keyAlias": "your_android_alias",
"keyPassword": "your_key_password"
}
}
Run Code Online (Sandbox Code Playgroud)
MY_PROJECT /安卓/应用/的build.gradle
// ...
signingConfigs {
release {
def credsFilePath = file("../../credentials.json").toString()
def credsFile = new File(credsFilePath, "").getText('UTF-8')
def json = new groovy.json.JsonSlurper().parseText(credsFile)
storeFile file(json.android.storeFile)
storePassword = json.android.storePassword
keyAlias = json.android.keyAlias
keyPassword = json.android.keyPassword
}
...
buildTypes {
release {
signingConfig signingConfigs.release //I added this
// ...
}
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
我选择.json文件类型而不是.properties文件类型(如在接受的答案中)的原因是因为我还希望将其他数据(我需要的其他自定义属性)存储到同一个文件(my_project/credentials.json)中,并且仍然使用gradle解析从该文件中签名信息.
可以使用任何现有的Android Studio gradle项目,并从命令行构建/签名,而无需编辑任何文件.这使得将项目存储在版本控制中同时保持密钥和密码分离而不是build.gradle文件非常好:
./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
Run Code Online (Sandbox Code Playgroud)
这个问题已经收到了许多有效的答案,但我想分享我的代码,这可能对库维护者有用,因为它使原始代码build.gradle非常干净。
我在模块目录中添加了一个文件夹gitignore。它看起来像这样:
/signing
/keystore.jks
/signing.gradle
/signing.properties
Run Code Online (Sandbox Code Playgroud)
keystore.jks并且signing.properties应该是不言自明的。而且signing.gradle是这样的:
def propsFile = file('signing/signing.properties')
def buildType = "release"
if (!propsFile.exists()) throw new IllegalStateException("signing/signing.properties file missing")
def props = new Properties()
props.load(new FileInputStream(propsFile))
def keystoreFile = file("signing/keystore.jks")
if (!keystoreFile.exists()) throw new IllegalStateException("signing/keystore.jks file missing")
android.signingConfigs.create(buildType, {
storeFile = keystoreFile
storePassword = props['storePassword']
keyAlias = props['keyAlias']
keyPassword = props['keyPassword']
})
android.buildTypes[buildType].signingConfig = android.signingConfigs[buildType]
Run Code Online (Sandbox Code Playgroud)
和原来的 build.gradle
apply plugin: 'com.android.application'
if (project.file('signing/signing.gradle').exists()) {
apply from: 'signing/signing.gradle'
}
android {
compileSdkVersion 27
defaultConfig {
applicationId ...
}
}
dependencies {
implementation ...
}
Run Code Online (Sandbox Code Playgroud)
如您所见,您根本不必指定 buildTypes,如果用户有权访问有效signing目录,他只需将其放入模块中,他就可以构建一个有效的签名发布应用程序,否则它只适用于他它通常会这样做。
受到/sf/answers/2325281031/的启发,进行了一些改进
androidReact Native 的文件夹中):app.keystorekeystore.properties.gitignorekeystore.properties添加STORE_FILE=app.keystore
KEY_ALIAS=app_alias
STORE_PASSWORD=your_password
KEY_PASSWORD=your_password
Run Code Online (Sandbox Code Playgroud)
app/build.gradle添加// Load keystore
def keystoreProperties = new Properties()
try {
def keystorePropertiesFile = rootProject.file("keystore.properties");
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
} catch(IOException e) {
// We don't have release keys, ignoring
}
...
android {
...
signingConfigs {
release {
if (keystoreProperties['STORE_FILE']) {
storeFile rootProject.file(keystoreProperties['STORE_FILE'])
storePassword keystoreProperties['STORE_PASSWORD']
keyAlias keystoreProperties['KEY_ALIAS']
keyPassword keystoreProperties['KEY_PASSWORD']
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Run Code Online (Sandbox Code Playgroud)
PS:欢迎进行编辑以改进常规逻辑
| 归档时间: |
|
| 查看次数: |
60638 次 |
| 最近记录: |