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

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


当前回答

就像@Destil说的,但允许其他没有钥匙的人建造: 比之前的答案更简单的方法:

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

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

修改构建。这样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 assemblerrelease 或 gradle构建

其他回答

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

我提出了一个简单的解决方案,使用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

释放快乐!

扩展David Vavra的回答,创建一个文件~/.gradle/gradle。属性和添加

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 {
  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创建一个安装…发布的任务。

基本信息。正如https://stackoverflow.com/a/19130098/3664487所指出的,“Gradle脚本可以使用System.console()提示用户输入。readLine方法。”不幸的是,Gradle总是会要求密码,即使你在构建一个调试版本(参见如何使用Gradle创建一个发布签名apk文件?)幸运的是,这是可以克服的,如上所述。

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

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构建类型并运行应用程序,而不必使用命令行。

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

把它放到~/.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的参考