如何使用Gradle创build发行版签名的apk文件?
我想让我的Gradle构build使用Gradle创build一个发行版签名的apk文件。
我不确定代码是否正确,或者在执行gradle build
时是否缺less参数?
这是我的gradle文件中的一些代码:
android { ... signingConfigs { release { storeFile file("release.keystore") storePassword "******" keyAlias "******" keyPassword "******" } } }
gradle构build完成SUCCESSFUL,并在我的build/apk
文件夹中,我只能看到...-release-unsigned.apk
和...-debug-unaligned.apk
文件。
有关如何解决这个问题的任何build议?
比以前的答案更容易:
把它放到~/.gradle/gradle.properties
RELEASE_STORE_FILE={path to your keystore} RELEASE_STORE_PASSWORD=***** RELEASE_KEY_ALIAS=***** RELEASE_KEY_PASSWORD=*****
像这样修改你的build.gradle
:
... signingConfigs { release { storeFile file(RELEASE_STORE_FILE) storePassword RELEASE_STORE_PASSWORD keyAlias RELEASE_KEY_ALIAS keyPassword RELEASE_KEY_PASSWORD } } buildTypes { release { signingConfig signingConfigs.release } } ....
然后你可以运行gradle assembleRelease
我设法解决它添加这个代码,并build立与gradle build
:
android { ... signingConfigs { release { storeFile file("release.keystore") storePassword "******" keyAlias "******" keyPassword "******" } } buildTypes { release { signingConfig signingConfigs.release } } }
这会生成一个签名的发行apk文件。
请注意,@ sdqali的脚本(至less在使用Gradle 1.6时)会在您调用任何 gradle任务时询问密码。 既然你在gradle assembleRelease
(或类似的)时只需要它,你可以使用下面的技巧:
android { ... signingConfigs { release { // We can leave these in environment variables storeFile file(System.getenv("KEYSTORE")) keyAlias System.getenv("KEY_ALIAS") // These two lines make gradle believe that the signingConfigs // section is complete. Without them, tasks like installRelease // will not be available! storePassword "notYourRealPassword" keyPassword "notYourRealPassword" } } ... } task askForPasswords << { // Must create String because System.readPassword() returns char[] // (and assigning that below fails silently) def storePw = new String(System.console().readPassword("Keystore password: ")) def keyPw = new String(System.console().readPassword("Key password: ")) android.signingConfigs.release.storePassword = storePw android.signingConfigs.release.keyPassword = keyPw } tasks.whenTaskAdded { theTask -> if (theTask.name.equals("packageRelease")) { theTask.dependsOn "askForPasswords" } }
请注意,我也不得不添加以下(在android下)使其工作:
buildTypes { release { signingConfig signingConfigs.release } }
如果您想避免在build.gradle中对密钥库和密码进行硬编码,则可以使用属性文件,如下所述: 使用GRADLE处理SIGNING CONFIGS
基本上:
1)在/ home / [username] /.signing中创build一个myproject.properties文件,内容如下:
keystore=[path to]\release.keystore keystore.password=********* keyAlias=*********** keyPassword=********
2)用以下内容创build一个gradle.properties文件(可能位于项目目录的根目录):
MyProject.properties=/home/[username]/.signing/myproject.properties
3)在你的build.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'] } } }
像@Destil说的,但允许其他谁没有钥匙build立:比以前的答案更容易的方式:
把它放到~/.gradle/gradle.properties
RELEASE_STORE_FILE={path to your keystore} RELEASE_STORE_PASSWORD=***** RELEASE_KEY_ALIAS=***** RELEASE_KEY_PASSWORD=*****
像这样修改你的build.gradle
:
... if(project.hasProperty("RELEASE_STORE_FILE")) { signingConfigs { release { storeFile file(RELEASE_STORE_FILE) storePassword RELEASE_STORE_PASSWORD keyAlias RELEASE_KEY_ALIAS keyPassword RELEASE_KEY_PASSWORD } } } buildTypes { if(project.hasProperty("RELEASE_STORE_FILE")) { release { signingConfig signingConfigs.release } } } ....
然后你可以运行gradle assembleRelease
或者gradle build
(回复上面的user672009 。)
一个更简单的解决scheme,如果你想保持你的密码出Git仓库; 然而,想要包含你的build.gradle,甚至可以和产品风格一起工作,就是创build一个单独的gradle文件。 我们称之为'signing.gradle'(包含在你的.gitignore中)。 就好像它是你的build.gradle文件减去与login它无关的所有东西。
android { signingConfigs { flavor1 { storeFile file("..") storePassword ".." keyAlias ".." keyPassword ".." } flavor2 { storeFile file("..") storePassword ".." keyAlias ".." keyPassword ".." } } }
然后在你的build.gradle文件中包含这行下面的“应用插件:”android“”
apply from: 'signing.gradle'
如果您没有或使用多种口味,请将上面的“flavor1”重命名为“release”,您应该完成。 如果你正在使用口味继续。
最后将你的口味链接到你的build.gradle文件中正确的signingConfig,你应该完成。
... productFlavors { flavor1 { ... signingConfig signingConfigs.flavor1 } flavor2 { ... signingConfig signingConfigs.flavor2 } } ...
这是对user672009的回复,除了sdqali的post之外 (他的代码会在IDE的“Run”button构builddebugging版本时崩溃):
您可以使用下面的代码:
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 { } } }
在较新的Android Studio中,有一个非常简单的GUI方法,它也填充了Gradle文件。
-
File -> Project Structure
-
Module ->
select主模块(“应用程序”或其他自定义名称) -
Signing
标签 – > Plus图像添加新的configuration -
在右侧填写数据
-
确定并且Gradle文件是自动创build的
-
您将手动在
builtTypes{release{}}
添加一行signingConfig signingConfigs.NameOfYourConfig
图片:
两个重要的(!)注释:
(编辑12/15)
-
要创build签名APK,您必须打开Android Studio的terminal选项卡(主界面的底部)并发出命令
./gradlew assembleRelease
-
如果您忘记了
keyAlias
(我经常遇到这种情况),您将不得不启动Build -> Generate Signed APK
来启动该进程并查看Alias键的名称。
如果你通过像我这样的命令行来构buildapk,那么你可以提供签名configuration作为参数。
将其添加到您的build.gradle
def getStore = { -> def result = project.hasProperty('storeFile') ? storeFile : "null" return result } def getStorePassword = { -> def result = project.hasProperty('storePassword') ? storePassword : "" return result } def getKeyAlias = { -> def result = project.hasProperty('keyAlias') ? keyAlias : "" return result } def getKeyPassword = { -> def result = project.hasProperty('keyPassword') ? keyPassword : "" return result }
让你的signingConfigs
像这样
signingConfigs { release { storeFile file(getStore()) storePassword getStorePassword() keyAlias getKeyAlias() keyPassword getKeyPassword() } }
然后你像这样执行gradlew
./gradlew assembleRelease -PstoreFile="keystore.jks" -PstorePassword="password" -PkeyAlias="alias" -PkeyPassword="password"
android { compileSdkVersion 17 buildToolsVersion "19.0.3" defaultConfig { minSdkVersion 9 targetSdkVersion 18 } File signFile = rootProject.file('sign/keystore.properties') if (signFile.exists()) { Properties properties = new Properties() properties.load(new FileInputStream(signFile)) signingConfigs { release { storeFile rootProject.file(properties['keystore']) storePassword properties['storePassword'] keyAlias properties['keyAlias'] keyPassword properties['keyPassword'] } } } buildTypes { release { runProguard true zipAlign true proguardFile rootProject.file('proguard-rules.cfg') signingConfig signingConfigs.release } debug { runProguard false zipAlign true } } }
使用git时自动应用Gradle签名
这是多么令人费解的方式,这是惊人的。 这是我自己的方式,我试图坚持谷歌自己的build议 。 但是,他们的解释还不是很清楚,所以我会详细介绍一下Linux的程序。
描述:
在构build过程中用于自动签署应用程序的默认Google指令 ,而不将密码和签名文件保留在您的应用程序开发(GIT)path中,是相当模糊的。 这里是澄清的一步一步的指示如何做到这一点。
最初的假设:
您在由以下path给出的目录中有一个名为“MyApp”的应用程序: $HOME/projects/mydev/MyApp
。 但是,MyApp目录是使用GIT控制的。
问题
我们显然不希望在GIT控制的目录中的任何地方有我们的签名或密码文件,即使我们能够很好地使用.gitignore
等,仍然是冒险的,容易犯错误。 所以我们希望我们的密钥库和签名文件在外面。
解
我们需要做三件事:
- 创buildAndroid Studio使用的密码文件
- 创build签名密钥文件
- 编辑模块
build.gradle
文件以使用(1)和(2)。
对于这个例子,我们命名这两个文件:
-
keystore.properties
-
MyApp-release-key.jks
我们可以把这两个文件放在这里:
cd $HOME/projects/mydev/
(1)创build密钥库密码文件
第一个文件包含在中使用的明文密码; 和(2)中释放密钥文件的path。 首先填写完毕,因为它会使复制粘贴操作更容易进行下一步。
cd $HOME/projects/mydev/
编辑keystore.properties
,使它的内容是:
storePassword=myStorePassword keyPassword=mykeyPassword keyAlias=myKeyAlias storeFile=myStoreFileLocation
这里唯一棘手的部分是myStoreFileLocation
。 这是构build期间从模块build.gradle
文件中看到的path。 这通常意味着类似于和相对于的path: $HOME/projects/mydev/MyApp/app/build.gradle
。 所以为了指向MyApp-release-key.jks
文件,我们需要放在这里:
../../../MyApp-release-key.jks
在这里,我们也为密钥select了“myapp”别名。 然后最后的文件应该看起来:
storePassword=myStorePassword keyPassword=mykeyPassword keyAlias=myapp storeFile=../../../MyApp-release-key.jks
(2)创build签名文件
第二个文件是在创build签名密钥时自动生成的。 如果您没有其他应用程序,并且这是您唯一的密钥库,那么请使用以下命令创build该文件:
cd $HOME/projects/mydev/ keytool -genkeypair -v -keystore MyApp-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias myapp
这会问你两个密码和一堆信息。 (与Android Studio中的相同)现在复制/粘贴您以前select的密码。
(3)编辑你的模块gradle.build
文件来使用上面的
以下部分需要出现在你的应用程序/模块的Gradle构build文件中。 首先, 在 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,你可以重新build立你的应用程序:
cd $HOME/projects/mydev/MyApp/app/ ./gradlew clean build
这应该会生成一个可以在Google Play中使用的正确签名的应用程序。
您也可以使用Gradle的-P命令行选项来帮助签名。 在你的build.gradle中,像这样添加唱歌组件:
signingConfigs { release { storeFile file("path/to/your/keystore") storePassword RELEASE_STORE_PASSWORD keyAlias "your.key.alias" keyPassword RELEASE_KEY_PASSWORD } }
然后像这样调用gradle构build:
gradle -PRELEASE_KEYSTORE_PASSWORD=******* -PRELEASE_KEY_PASSWORD=****** build
如果您愿意,可以使用-P来设置storeFile和keyAlias。
这基本上是Destil的解决scheme,但使用命令行选项。
有关gradle属性的更多详细信息,请查看gradle用户指南 。
如果你可以在所有的项目中重复使用相同的configuration,那么Destil的答案是很好的。 或者,Android Studio附带了一个local.properties
文件,可以用来代替,但是它应该是由IDE生成的,我无法从Android Studio中find扩展它的方法。
这是@ jonbo的答案的变化。 这个答案允许项目特定的设置,但它有一些开发人员的开销。 具体来说,需要使用重要的样板将signingConfigs
定义转换为单独的文件 – 尤其是如果您需要为多个项目执行此操作,这是通过Destilselect此解决scheme的主要原因。 这也可以通过也包括该线来缓解
apply plugin: 'com.android.application'
在凭证文件中,因为这将允许IDE完成。
最后,这里的大多数解决scheme都不允许在debugging模式下构build项目 – 该模式会自动处理debugging签名 – 如果不提供语义上有效的signingConfigs
定义,则不提供语法。 如果您不需要从给定的机器生成发布版本,那么这个额外的步骤可能被视为不必要的障碍。 另一方面,它可以帮助无知或懒惰的同事在生产中运行debugging版本。
这个解决scheme将允许debugging版本,而不用担心凭证,但是它需要有效的证书来生成发布版本,而且只需要很less的样板。 然而,作为一个缺点, 它可能会鼓励其他人用真实的凭据取代虚拟价值观,而且没有办法保护这一点。
// 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 ... } } }
这将创build一个虚拟属性,纯粹用于生成语法上有效的构build文件。 就debugging版本而言,分配给ext.signing
属性的值是不相关的。 要启用发布版本, ext.signing
复制到ext.signing
并用有效凭证replace虚拟值。
// signing.gradle ext.signing = [ storeFilePath : 'real/keystore', storePassword : 'real keystore password', keyAlias : 'real key alias', keyPassword : 'real key password', ]
当然,VCS应该忽略签名。
现在几乎所有的平台都提供了某种钥匙环,所以没有理由留下明文密码。
我提出了一个简单的解决scheme,它使用Python Keyring模块 (主要是配套的控制台脚本keyring
)和Groovy ['do', 'something'].execute()
)的最小包装器['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 assembleRelease
之前,您必须在密钥环中只设置一次密码:
$ keyring set google-play android.keystore # will be prompted for the passwords $ keyring set google-play com.example.app
快乐版本!
我觉得这个很有趣。 这是我的步行。
A到Z如何在IntelliJ(v.13.1.4)中创buildgradle构build文件的演练本演练假定您知道如何创build密钥库文件。 对于本教程的工作,您需要将您的密钥库文件放在您的应用程序文件夹中,并且需要将您的zipalign.exe文件放在“SDK-ROOT \ tools”中。 这个文件通常在'SDK-ROOT \ build-tools'中find,并且在这个文件夹下它将会在最高的api文件夹(alpha或beta我推荐alpha版本)。
对于那些希望直接跳到这里的是gradle构build文件。
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.9.+' } } apply plugin: 'android' repositories { mavenCentral() } android { compileSdkVersion 19 buildToolsVersion '20.0.0' defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" } signingConfigs { playstore { keyAlias 'developers4u' keyPassword 'thisIsNotMyRealPassword' storeFile file('developers4u.keystore') storePassword 'realyItIsNot' } } buildTypes { assembleRelease { debuggable false jniDebugBuild false runProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' zipAlign true signingConfig signingConfigs.playstore } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:20.0.0' compile 'com.android.support:appcompat-v7:20.0.0' }
您可以从菜单选项构build该构build文件的一部分(上图):文件/项目结构从这里select构面,然后单击“Android Gradle(App)”。 从这里你将看到标签:“属性”,“签名”,“味道”,“构buildtypes”和“依赖”,我们将只使用“签名”和“构buildtypes”。 在“构buildtypes”(在名称部分)下,input您希望标识您的构buildtypesconfiguration的名称,在其他4个字段中input您的密钥库信息(将密钥库path设置为您的应用程序文件夹下的那个)。
在“构buildtypes”下,在名称字段中input值“assembleRelease”,将“Debuggable”设置为false,“Jni Debug Build”应该为false,将“Run Proguard”设置为true并将“Zip Align”设置为true。 这将生成构build文件,但不是如上所述,你将不得不添加到生成文件的一些事情后。 ProGuard文件位置将在Gradle构build文件中手动设置。 (如上所述)
您将不得不添加的DSL容器如下所示:
android { .... compileSdkVersion 19 buildToolsVersion '20.0.0' defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" } .... }
您还必须添加:
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:20.0.0' compile 'com.android.support:appcompat-v7:20.0.0' }
注意上面这个DSL容器('dependencies')应该在configuration文件的底部,但不在android DSL容器内。 为了从IntelliJ菜单构build依赖关系容器,请select:文件/项目结构。 从那里再次selectFacets,然后selectAndroid-Gradle(应用程序)。 你会看到上面提到的5个标签。 select“依赖项”选项卡并添加所需的依赖项。
完成这一切之后,您应该看到一个Gradle构build文件,与本演练顶部的文件类似。 要构build您签名的zip压缩版本,您需要打开Gradle任务。 你可以通过selectView / Tool Windows / Gradle来进入这个窗口。 从这里你可以双击'assembleAssembleRelease。 这应该会生成可部署的APK。
编译你的发行版时可能出现的问题是(但不限于):你的Gradle构build文件位于错误的地方。 有两个Gradle构build文件; 一个在应用程序根文件夹中,另一个在应用程序根下的应用程序文件夹中。 你必须使用后者。
你也可能有皮毛问题。 (注意:Android Developer Studio在检测Lint问题方面要比IntelliJ更好,当您尝试从菜单选项生成已签名的APK时,您会注意到这一点)
为了解决lint问题,您需要将以下DSL容器放在android容器(位于顶部):
android { .... lintOptions { abortOnError false } .... }
把这个里面你的android DSL容器将导致生成文件夹中的错误文件(直接在你的应用程序文件夹下)文件名应该像'lint-results-release-fatal.html'这个文件会告诉你发生错误的类。 另一个将生成的文件是一个XML文件,其中包含与lint错误关联的“问题ID”。 文件名应该像“lint-results-release-fatal.xml”。 在文件顶部附近的某处,您将看到一个节点“问题”,其中您将看到类似于“id =”IDOfYourLintProblem“
要解决这个问题,请打开项目中“lint-results-assembleRelease-fatal.html”文件中列出的文件,并在Java类文件的类名称上方input以下代码行:@SuppressLint(“IDOfYourLintProblem “)。 你可能不得不导入'android.annotation.SuppressLint'
所以你的java类文件应该显示如下:
package com.WarwickWestonWright.developers4u.app.CandidateArea; import android.annotation.SuppressLint; ... other imports @SuppressLint("IDOfYourLintProblem") public class SearchForJobsFragment extends Fragment {... rest of your class definition}
请注意,抑制lint错误并不总是最好的IDEA,您可能最好更改导致lint错误的代码。
另一个可能发生的问题是,如果您没有为Gradle HOME环境variables设置环境variables。 这个variables被命名为“GRADLE_HOME”,应该设置gradle home目录的path,比如'C:\ gradle-1.12'。有时候你可能想把'ANDROID_HOME'的环境variables设置为'YOUR- SDK-ROOT \ SDK”
完成之后,返回到Gradle任务窗口并双击assembleAssembleRelease。
如果一切顺利,您应该能够进入文件夹app \ build \ apk并find您的可部署APK文件。
由David Vavra扩展答案,创build一个文件〜/ .gradle / gradle.properties并添加
RELEASE_STORE_FILE=/path/to/.keystore RELEASE_KEY_ALIAS=XXXXX RELEASE_STORE_PASSWORD=XXXXXXXXX RELEASE_KEY_PASSWORD=XXXXXXXXX
然后在build.gradle
signingConfigs { release { } } buildTypes { release { minifyEnabled true shrinkResources true } } // make this optional if ( project.hasProperty("RELEASE_KEY_ALIAS") ) { signingConfigs { release { storeFile file(RELEASE_STORE_FILE) storePassword RELEASE_STORE_PASSWORD keyAlias RELEASE_KEY_ALIAS keyPassword RELEASE_KEY_PASSWORD } } buildTypes { release { signingConfig signingConfigs.release } } }
我有几个问题,我把下面一行放在一个错误的地方:
signingConfigs { release { // We can leave these in environment variables storeFile file("d:\\Fejlesztés\\******.keystore") keyAlias "mykey" // These two lines make gradle believe that the signingConfigs // section is complete. Without them, tasks like installRelease // will not be available! storePassword "*****" keyPassword "******" } }
确保你在android部分中放置了签名configuration部分:
android { .... signingConfigs { release { ... } } }
代替
android { .... } signingConfigs { release { ... } }
犯这个错误很容易。
另一种解决同样问题的方法。 由于不build议在源代码中存储任何types的凭证,因此我们决定将密钥存储区和密钥别名的密码设置在单独的属性文件中,如下所示:
key.store.password=[STORE PASSWORD] key.alias.password=[KEY PASSWORD]
如果你使用git,你可以创build一个名为secure.properties的文本文件。 你应该确保从你的仓库中排除它(如果使用git,将它添加到.gitignore文件)。 然后,您需要创build一个签名configuration,就像其他答案指出的一样。 唯一的区别是你将如何加载凭证:
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') } ... } }
Never forget to assign the signingConfig to the release build type manually (for some reason I sometimes assume it will be used automatically). Also, it is not mandatory to enable proguard, but it is recommendable.
We like this approach better than using environment variables or requesting user input because it can be done from the IDE, by switching to the realease build type and running the app, rather than having to use the command line.
To complement the other answers, you can also place your gradle.properties file in your own module folder, together with build.gradle, just in case your keystore is specific to one project.
i am work in Ubuntu14.04. vim ~/.bashrc and add export ANDROID_KEYSTORE= export ANDROID_KEYALIAS=
and then in build.gradle set.
final Console console = System.console(); if (console != null) { // Building from console signingConfigs { release { storeFile file(System.getenv("KEYSTORE")) storePassword new String(System.console().readPassword("\n\$ Enter keystore password: ")) keyAlias System.getenv("KEY_ALIAS") keyPassword new String(System.console().readPassword("\n\$ Enter key password: ")) } } } else { // Building from IDE's "Run" button signingConfigs { release { } } }
An alternative is to define a task that runs only on release builds.
android { ... signingConfigs { release { // We can leave these in environment variables storeFile file('nameOfKeystore.keystore') keyAlias 'nameOfKeyAlias' // These two lines make gradle believe that the signingConfigs // section is complete. Without them, tasks like installRelease // will not be available! storePassword "notYourRealPassword" keyPassword "notYourRealPassword" } } buildTypes { ... release { signingConfig signingConfigs.release ... } } ... } task setupKeystore << { final Console console = System.console(); if (console != null) { //def keyFile = console.readLine(“\nProject: “ + project.name + “Enter keystore path: ")) //def keyAlias = console.readLine(“Project: “ + project.name + “Enter key alias: ") def storePw = new String(console.readPassword(“Project: “ + project.name + “. Enter keystore password: ")) def keyPw = new String(console.readPassword(“Project: “ + project.name + “.Enter keystore password: ")) //android.signingConfigs.release.storeFile = file(keyFile); //android.signingConfigs.release.keyAlias = keyAlias android.signingConfigs.release.storePassword = storePw android.signingConfigs.release.keyPassword = keyPw } } //Validate t def isReleaseConfig = gradle.startParameter.taskNames.any {it.contains('Release') } if (isReleaseConfig) { setupKeystore.execute(); }
You can request passwords from the command line:
... signingConfigs { if (gradle.startParameter.taskNames.any {it.contains('Release') }) { release { storeFile file("your.keystore") storePassword new String(System.console().readPassword("\n\$ Enter keystore password: ")) keyAlias "key-alias" keyPassword new String(System.console().readPassword("\n\$ Enter keys password: ")) } } else { //Here be dragons: unreachable else-branch forces Gradle to create //install...Release tasks. release { keyAlias 'dummy' keyPassword 'dummy' storeFile file('dummy') storePassword 'dummy' } } } ... buildTypes { release { ... signingConfig signingConfigs.release } ... } ...
The if-then-else
block prevents requests for passwords when you're building a release. Although the else
branch is unreachable, it tricks Gradle into creating an install...Release
task.
Backstory . As noted by https://stackoverflow.com/a/19130098/3664487 , " Gradle scripts can prompt for user input using the System.console().readLine method ." Unfortunately, Gradle will always request a password, even when you're building a debug release (cf. How to create a release signed apk file using Gradle? ). Fortunately, this can be overcome, as I have shown above.
if you don't want to see Cannot invoke method readLine() on null object. you need write in gradle.properties first.
KEYSTORE_PASS=***** ALIAS_NAME=***** ALIAS_PASS=*****
If you, like me, just want to be able to run the release on your device for testing purposes, consider creating a second keystore for signing, so you can simply put the passwords for it into your build.gradle without worrying for your market key store security.
You can create a new keystore by clicking Build/Generate Signed APK/Create new…