如何使用Gradle创建一个发布签名的apk文件?

时间:2013-08-20 06:53:47

标签: android gradle apk release android-gradle

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

我不确定代码是否正确或者在执行gradle build时是否缺少参数?

这是我的gradle文件中的一些代码:

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

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

有关如何解决此问题的任何建议?

31 个答案:

答案 0 :(得分:365)

比以前的答案更容易:

将其放入~/.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

答案 1 :(得分:249)

我设法解决了添加此代码的问题,并使用gradle build构建:

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

这会生成一个签名版本的apk文件。

答案 2 :(得分:65)

请注意,@ sdqali的脚本(至少在使用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
    }
}

答案 3 :(得分:57)

如果你想避免硬编码你的密钥库&amp; build.gradle 中的密码,您可以使用此处所述的属性文件:HANDLING SIGNING CONFIGS WITH GRADLE

基本上:

1)使用以下内容在 / home / [用户名] /。签名创建myproject.properties文件:

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

2)使用内容创建一个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']
        }
    }
}

答案 4 :(得分:34)

像@Destil所说,但允许其他没有密钥构建的人: 比以前的答案更容易:

将其放入~/.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

答案 5 :(得分:31)

使用git

时使用Gradle自动进行应用程序签名

令人惊讶的是,有多少令人费解的方式可以做到这一点。这是我自己的方式,我尝试坚持谷歌自己的recommendation。但是,他们的解释并不完全清楚,因此我将详细介绍Linux的过程。

说明

自动签署应用的默认Google instructions 在构建期间,不保留密码和签名文件 在您的应用开发(GIT)路径中,相当模糊。这里有 澄清了如何执行此操作的逐步说明。

初步假设:

您在以下路径指定的目录中有一个名为“MyApp”的应用: $HOME/projects/mydev/MyApp。但是,使用了MyApp目录 用GIT控制。

enter image description here

问题

我们显然不希望在任何地方都有我们的签名或密码文件 GIT控制的目录,即使我们非常能够使用.gitignore等,它仍然过于冒险而且容易出错。所以我们想要我们的密钥库和签名文件。

解决方案

我们需要做三(3)件事:

  1. 创建供Android Studio使用的密码文件
  2. 创建签名密钥文件
  3. 编辑模块build.gradle文件以使用(1)和(2)。
  4. 在本例中,我们将这两个文件命名为:

    1. keystore.properties
    2. MyApp-release-key.jks
    3. 我们可以将这两个文件放在这里:

      cd $HOME/projects/mydev/
      

      (1)创建密钥库密码文件

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

      cd $HOME/projects/mydev/
      

      修改keystore.properties,使其内容为:

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

      这里唯一棘手的部分是myStoreFileLocation。这是构建期间从模块build.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.build文件以使用上述

      您的app / module的Gradle构建文件中需要包含以下部分。首先,在<{1}}阻止之前添加以下 之前的行。

      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 {}

      现在,您可以使用shell重新构建应用:

      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
                  ...
              }
          }
      }
      

      这应生成一个可在Google Play中使用的已正确签名的应用。

      更新: 2019-04-02

      cd $HOME/projects/mydev/MyApp/app/ ./gradlew clean build 某些的更新版本告诉您应该使用基于 PKCS12 的密钥文件,而不是上面使用的原始/默认密码文件。 他们然后告诉你应该转换为新的开放PKCS12格式。但是,似乎Android开发工具还没有为此做好准备,因为如果你这样做,你将得到以下奇怪的错误:

        

      keytool无法读取密钥   来自商店“F:\ XXX \ XXX.jks”的XXX:获取密钥失败:给定最终阻止   适当填充。如果在期间使用坏密钥,则可能出现此类问题   解密。

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

答案 6 :(得分:27)

(回复上面的user672009。)

更简单的解决方案,如果您想将密码保存在git存储库之外;但是,想要在其中包含build.gradle,即使对于产品风格也很好,就是创建一个单独的gradle文件。我们称之为'signing.gradle'(将其包含在你的.gitignore中)。就好像它是你的build.gradle文件减去与登录无关的一切。

android {
    signingConfigs { 
        flavor1 {
            storeFile file("..")
            storePassword ".."
            keyAlias ".."
            keyPassword ".."
        }
        flavor2 {
            storeFile file("..")
            storePassword ".."
            keyAlias ".."
            keyPassword ".."
        }
    }
}

然后在你的build.gradle文件中包含这行“apply plugin:'android'”

 apply from: 'signing.gradle'

如果您没有或使用多种口味,请将“flavor1”重命名为“release”,然后您应该完成。如果你正在使用口味继续。

最后将你的口味链接到build.gradle文件中正确的signingConfig,你就应该完成了。

  ...

  productFlavors {

      flavor1 {
          ...
          signingConfig signingConfigs.flavor1
      }

      flavor2 {
          ...
          signingConfig signingConfigs.flavor2
      }
  }

  ...

答案 7 :(得分:17)

这是对user672009的回复和sdqali's post的补充(他的代码将因IDE的“运行”按钮构建调试版本而崩溃):

您可以使用以下代码:

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 {

        }
    }

}

答案 8 :(得分:15)

如果你像我一样通过命令行构建apk,那么你可以提供签名配置作为参数。

将此添加到您的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"

答案 9 :(得分:14)

在较新的Android Studio中,有一种非常简单的GUI方式,它也可以填充Gradle文件。

  1. File -> Project Structure

  2. Module ->选择主要模块('app'或其他自定义名称)

  3. Signing标签 - &gt;加上图片添加新配置

  4. 在右侧填写数据

  5. 确定并自动创建Gradle文件

  6. 您需要在signingConfig signingConfigs.NameOfYourConfig

  7. 内手动添加一行builtTypes{release{}}

    图片:

    enter image description here

    enter image description here

    两个重要的(!)注释:

    (编辑12/15)

    1. 要创建已签名的APK,您必须打开Android Studio的终端标签(主界面的底部)并发出命令./gradlew assembleRelease

    2. 如果您忘记了keyAlias(我经常发生的事情),您必须启动Build -> Generate Signed APK才能启动该过程并查看别名密钥的名称。

答案 10 :(得分:12)

如果您已经拥有密钥库文件,那么就像在构建命令中添加一些参数一样简单:

./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

答案 11 :(得分:10)

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
        }
    }
}

答案 12 :(得分:9)

您还可以使用gradle的 -P 命令行选项来帮助签名。在你的build.gradle中,添加如下的singingConfigs:

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的解决方案,但使用命令行选项。

有关gradle属性的更多详细信息,请查看gradle user guide

答案 13 :(得分:6)

如果你可以在所有项目中重复使用相同的配置,那么@ destil的答案是好的。或者,Android Studio附带一个local.properties文件,可以替代使用,但它应该是IDE生成的,我无法找到从Android Studio中扩展它的方法。

这是@jonbo's answer的变体。该答案允许项目特定的设置,但它带来一些开发人员的开销。具体而言,需要使用重要的样板来将signingConfigs定义移动到单独的文件中 - 特别是如果您需要为多个项目执行此操作,这是在Destil上选择此解决方案的主要原因。这可以通过包括行

来稍微缓解
apply plugin: 'com.android.application'

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

最后,这里的大多数解决方案 not 允许在调试模式下构建项目 - 它自动处理调试签名 - 而不提供语法上(如果不是语义上有效的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',
]

当然,VCS应忽略signing.gradle

答案 14 :(得分:5)

扩展David Vavra的答案,创建一个文件〜/ .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
      }
    }
  }

答案 15 :(得分:5)

现在几乎所有平台都提供某种密钥环,因此没有理由留下明文密码。

我提出了一个简单的解决方案,它使用Python Keyring module(主要是配套控制台脚本keyring)和Groovy ['do', 'something'].execute() feature周围的最小包装:

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

快乐发布!

答案 16 :(得分:4)

我非常有趣地想出这一个。这是我的演练。

A到Z介绍如何在IntelliJ中创建gradle构建文件(v.13.1.4) 本演练假定您知道如何创建密钥库文件。 要使本教程起作用,您需要将密钥库文件放在app文件夹中,并且需要将zipalign.exe文件放在“SDK-ROOT \ tools”中。这个文件通常位于'SDK-ROOT \ build-tools'中,在这个文件夹下,它将位于最高的api文件夹中(alpha或beta我建议使用alpha版本)。

对于那些希望直接跳到这里的人来说,是gradle构建文件。

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 {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:20.0.0'
    implementation 'com.android.support:appcompat-v7:20.0.0'
}

您可以从菜单选项:文件/项目结构构建此构建文件的一部分(上图) 从这里选择Facets并单击'Android-Gradle(App)。 从这里你会看到标签:'属性','签名','味道','构建类型'和'依赖关系'这个演练我们将使用'签名'和'构建类型'。 在“构建类型”(在名称部分)下,输入您希望识别构建类型配置的任何名称,并在其他4个字段中输入您的密钥库信息(将密钥库路径设置为您的app文件夹下的那个)。

在“构建类型”下,在名称字段中输入值'assembleRelease','Debuggable'应设置为false,'Jni Debug Build'应为false,将'Run Proguard'设置为true并'Zip Align'为真。这将生成构建文件,但不是如上所述,之后您将不得不向构建文件添加一些内容。此处的ProGuard文件位置将在gradle构建文件中手动设置。 (如上所述)

之后您必须添加的DSL容器如下:

android {
    ....
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    ....
}

您还必须添加:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:20.0.0'
    implementation 'com.android.support:appcompat-v7:20.0.0'
}
注意上面的这个DSL容器('dependencies')应该在配置文件的底部,但不在android DSL容器内。 要从IntelliJ菜单构建依赖项容器,请选择:文件/项目结构。从那里再次选择Facets然后选择Android-Gradle(app)。您将看到与上面提到的相同的5个选项卡。选择“依赖关系”选项卡并添加所需的依赖关系。

完成所有这些操作后,您应该会看到一个Gradle构建文件,类似于此演练顶部的文件。 要构建已签名的zip对齐版本,您需要打开Gradle任务。您可以通过选择View / Tool Windows / Gradle来访问此窗口。 从这里你可以双击'assembleAssembleRelease。这应该会生成可部署的APK。

编译发布时可能出现的问题是(但不限于):Gradle构建文件位于错误的位置。有两个Gradle构建文件;一个在应用程序根文件夹中,另一个在应用程序根目录下的app文件夹中。你必须使用后者。

您可能还有皮棉问题。 (注意:Android Developer Studio在发现Lint问题方面要比IntelliJ好得多,你会在尝试从菜单选项中生成签名的APK时注意到这一点)

要解决lint问题,你需要将以下DSL容器放在android容器中(在顶部):

android {
        ....
    lintOptions {
        abortOnError false
    }
    ....
}
将它放入你的android DSL容器中会导致在build文件夹中生成错误文件(直接在你的app文件夹下)文件名应该是'lint-results-release-fatal.html'这个文件将告诉你发生错误的类。将生成的另一个文件是一个XML文件,其中包含与lint错误关联的“问题ID”。文件名应该类似于'lint-results-release-fatal.xml'。在文件顶部附近的某处,您将看到一个节点“问题”,您将在其中看到类似于'id =“IDOfYourLintProblem”'

的内容

要解决此问题,请在项目中打开“lint-results-assembleRelease-fatal.html”文件中列出的文件,然后在类名称上方的Java类文件中输入以下代码行:@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环境变量设置环境变量,则可能发生的另一个问题。这个变量名为'GRADLE_HOME',应该设置gradle主目录的路径,比如'C:\ gradle-1.12' 有时您可能还想为'ANDROID_HOME'设置环境变量,将其设置为'YOUR-SDK-Root \ sdk'

完成此操作后,返回Gradle任务窗口并双击assembleAssembleRelease。

如果一切顺利,您应该可以转到app \ build \ apk文件夹找到可部署的APK文件。

答案 17 :(得分:3)

Android Studio 转到文件 - &gt;项目结构或按Ctrl + Alt + Shift + S

参见图片

enter image description here

单击确定

然后,signedConfigs将在build.gradle文件中生成。

enter image description here

答案 18 :(得分:3)

对于Groovy(build.gradle)

您不应将签名凭证直接放置在 build.gradle 文件中。相反,凭据应来自不受版本控制的文件。

放入文件 signing.properties ,在其中找到特定于模块的 build.gradle 。不要忘记将其添加到您的 .gitignore 文件中!

signing.properties

storeFilePath=/home/willi/example.keystore
storePassword=secret
keyPassword=secret
keyAlias=myReleaseSigningKey

build.gradle

android {
    // ...
    signingConfigs{
        release {
            def props = new Properties()

            def fileInputStream = new FileInputStream(file('../signing.properties'))
            props.load(fileInputStream)
            fileInputStream.close()

            storeFile = file(props['storeFilePath'])
            storePassword = props['storePassword']
            keyAlias = props['keyAlias']
            keyPassword = props['keyPassword']
        }
    }

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

答案 19 :(得分:3)

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

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并非强制要求,但建议使用。

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

答案 20 :(得分:2)

对于Kotlin脚本(build.gradle.kts)

您不应将签名凭据直接放置在 build.gradle.kts 文件中。相反,凭据应来自不受版本控制的文件。

放入文件 signing.properties ,在其中找到特定于模块的 build.gradle.kts 。不要忘记将其添加到您的 .gitignore 文件中!

signing.properties

storeFilePath=/home/willi/example.keystore
storePassword=secret
keyPassword=secret
keyAlias=myReleaseSigningKey

build.gradle.kts

android {
    // ...
    signingConfigs {
        create("release") {
            val properties = Properties().apply {
                load(File("signing.properties").reader())
            }
            storeFile = File(properties.getProperty("storeFilePath"))
            storePassword = properties.getProperty("storePassword")
            keyPassword = properties.getProperty("keyPassword")
            keyAlias = "release"
        }
    }

    buildTypes {
        getByName("release") {
            signingConfig = signingConfigs.getByName("release")
            // ...
        }
    }
}

答案 21 :(得分:2)

我有几个问题,我把以下一行放在错误的地方:

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 "******"
    }
}

确保将signingConfigs部分放在android部分中:

android
{
    ....
    signingConfigs {
        release {
          ...
        }
    }
}

而不是

android
{
    ....
}

signingConfigs {
   release {
        ...
   }
}

很容易犯这个错误。

答案 22 :(得分:1)

您可以从命令行请求密码:

...

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
  }

  ...
}

...

if-then-else阻止在您构建版本时阻止对密码的请求。虽然else分支无法访问,但它会欺骗Gradle创建install...Release任务。

<强>背景故事即可。如https://stackoverflow.com/a/19130098/3664487所述,&#34; Gradle脚本可以使用System.console()。readLine方法提示用户输入。&#34;不幸的是,Gradle将始终请求密码,即使您正在构建调试版本(参见How to create a release signed apk file using Gradle?)。幸运的是,正如我上面所示,这可以克服。

答案 23 :(得分:1)

另一种方法是定义仅在发布版本上运行的任务。

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();
}

答案 24 :(得分:1)

我在Ubuntu14.04工作。 vim~ / .bashrc并添加 export ANDROID_KEYSTORE = export ANDROID_KEYALIAS =

然后在build.gradle中。

    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 {

        }
    }

}

答案 25 :(得分:1)

现在是2019年,我需要使用V1(罐子签名)或V2(完整的APK签名)签署APK。我用谷歌搜索“生成签名的apk gradle”,它把我带到了这里。所以我在这里添加我的原始解决方案。

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

我最初的问题:How to use V1 (Jar signature) or V2 (Full APK signature) from build.gradle file

答案 26 :(得分:1)

为了补充其他答案,您还可以将gradle.properties文件与build.gradle一起放在您自己的模块文件夹中,以防您的密钥库特定于一个项目。

答案 27 :(得分:0)

使用react-native-config包在React-Native中添加了实现方法。
创建一个.env文件:

RELEASE_STORE_PASSWORD=[YOUR_PASSWORD]
RELEASE_KEY_PASSWORD=[YOUR_PASSWORD]

请注意,这不应该是版本控制的一部分。

在您的build.gradle中:

signingConfigs {
        debug {
            ...
        }
        release {
            storeFile file(RELEASE_STORE_FILE)
            storePassword project.env.get('RELEASE_STORE_PASSWORD')
            keyAlias RELEASE_KEY_ALIAS
            keyPassword project.env.get('RELEASE_KEY_PASSWORD')
        }
    }

答案 28 :(得分:0)

就我而言,我将错误的APK上传到另一个应用的发行版中。

答案 29 :(得分:-1)

如果您和我一样希望能够在设备上运行该版本以进行测试,请考虑创建第二个密钥库进行签名,这样您就可以简单地输入密码将它放入build.gradle ,而不必担心市场密钥库的安全性。

您可以通过单击构建/生成签名APK /创建新...

来创建新的密钥库

答案 30 :(得分:-1)

如果您不想看到无法在null对象上调用方法readLine()。,您需要先写入 gradle.properties

KEYSTORE_PASS=*****
ALIAS_NAME=*****
ALIAS_PASS=*****