android - studio - has subido un apk con una firma no válida
Copia del archivo APK en el proyecto Android Gradle (6)
Así es como copio mappings.txt cada vez que se ejecuta Proguard
tasks.whenTaskAdded { task ->
if (task.name.startsWith("proguard")) {//copy proguard mappings
task << {
copy {
from buildDir.getPath() + "/proguard"
into ''../proguard''
include ''**/mapping.txt''
}
println "PROGUARD FILES COPIED"
}
}
}
build.gradle
agregar una tarea personalizada al build.gradle
mi proyecto Android para copiar el APK final y el mapping.txt de Proguard en un directorio diferente. Mi tarea depende de la tarea assembleDevDebug
:
task publish(dependsOn: ''assembleDevDebug'') << {
description ''Copies the final APK to the release directory.''
...
}
Puedo ver cómo hacer una copia de archivo usando el tipo de tarea Copy
estándar, según los documentos:
task(copy, type: Copy) {
from(file(''srcDir''))
into(buildDir)
}
pero eso supone que sabes el nombre y la ubicación del archivo que deseas copiar.
¿Cómo puedo encontrar el nombre y la ubicación exactos del archivo APK que se creó como parte de la tarea assembleDevDebug
? ¿Está disponible como una propiedad? Se siente como si pudiera declarar los archivos como entradas para mi tarea, y declararlos como salidas de la tarea de assemble
, pero mi Gradle-fu no es lo suficientemente fuerte.
Tengo una lógica personalizada para inyectar el número de versión en el nombre del archivo APK, por lo que mi tarea de publish
no puede asumir el nombre y la ubicación predeterminados.
El siguiente código es lo que estoy usando para archivar el mapeo de apk y proguard en un archivo zip para cada variante con el tipo de compilación ''release'':
def releasePath = file("${rootDir}/archive/${project.name}")
def releaseTask = tasks.create(name: ''release'') {
group ''Build''
description "Assembles and archives all Release builds"
}
android.applicationVariants.all { variant ->
if (variant.buildType.name == ''release'') {
def build = variant.name.capitalize()
def releaseBuildTask = tasks.create(name: "release${build}", type: Zip) {
group ''Build''
description "Assembles and archives apk and its proguard mapping for the $build build"
destinationDir releasePath
baseName variant.packageName
if (!variant.buildType.packageNameSuffix) {
appendix variant.buildType.name
}
if (variant.versionName) {
version "${variant.versionName}_${variant.versionCode}"
} else {
version "$variant.versionCode"
}
def archiveBaseName = archiveName.replaceFirst(//.${extension}$/, '''')
from(variant.outputFile.path) {
rename ''.*'', "${archiveBaseName}.apk"
}
if (variant.buildType.runProguard) {
from(variant.processResources.proguardOutputFile.parent) {
include ''mapping.txt''
rename ''(.*)'', "${archiveBaseName}-proguard_/$1"
}
}
}
releaseBuildTask.dependsOn variant.assemble
variant.productFlavors.each { flavor ->
def flavorName = flavor.name.capitalize()
def releaseFlavorTaskName = "release${flavorName}"
def releaseFlavorTask
if (tasks.findByName(releaseFlavorTaskName)) {
releaseFlavorTask = tasks[releaseFlavorTaskName]
} else {
releaseFlavorTask = tasks.create(name: releaseFlavorTaskName) {
group ''Build''
description "Assembles and archives all Release builds for flavor $flavorName"
}
releaseTask.dependsOn releaseFlavorTask
}
releaseFlavorTask.dependsOn releaseBuildTask
}
}
}
Crea tareas como las siguientes:
- release - Ensambla y archiva todas las versiones de Release
- releaseFree - Ensambla y archiva todas las versiones de lanzamiento para darle sabor
- releaseFreeRelease: ensambla y archiva apk y su mapeo proguard para la compilación FreeRelease
- releasePaid: ensambla y archiva todas las compilaciones de lanzamiento para el sabor Pagado
- releasePaidRelease - Assembles and archives apk y su mapeo proguard para la compilación PaidRelease
El contenido del archivo / projectName / packageName-buildType-versionName_versionCode.zip sería:
- packageName-buildType-versionName_versionCode.apk
- packageName-buildType-versionName_versionCode-proguard_mapping.txt
Por lo general, el complemento de Android pondrá los apk en el directorio APP / build / apk.
Entonces, ejecuta assembleDebug
luego ls APP/build/apk
y deberías ver:
- APP-debug-unaligned.apk
- APP-release-unaligned.apk
- APP-release-unsigned.apk
- APP-release.apk, etc.
Si puede obtener el objeto variante asociado con devDebug, puede consultarlo con getOutputFile ().
Entonces, si quisieras publicar todas las variantes, tendrías algo como esto:
def publish = project.tasks.create("publishAll")
android.applicationVariants.all { variant ->
def task = project.tasks.create("publish${variant.name}Apk", Copy)
task.from(variant.outputFile)
task.into(buildDir)
task.dependsOn variant.assemble
publish.dependsOn task
}
Ahora puede llamar a gradle publishAll
y publicará todas sus variantes.
Un problema con el archivo de asignación es que la tarea de Proguard no le proporciona un getter a la ubicación del archivo, por lo que no puede consultarlo actualmente. Estoy esperando arreglar esto.
Tengo algunos buenos consejos aquí, pero también tuve un momento difícil para hacer lo que quería. Aquí está mi versión final:
def archiveBuildTypes = ["distribute"];
def archiveFlavors = ["googleplay"]
android.applicationVariants.all { variant ->
if (variant.buildType.name in archiveBuildTypes) {
variant.productFlavors.each { flavor ->
if (flavor.name in archiveFlavors) {
def taskSuffix = variant.name.capitalize()
def version = "${android.defaultConfig.versionCode} (${android.defaultConfig.versionName})" // assumes that versionName was especified here instead of AndroidManifest.xml
def destination = "${rootDir}/${project.name}/archive/${version}"
def assembleTaskName = "assemble${taskSuffix}"
if (tasks.findByName(assembleTaskName)) {
def copyAPKTask = tasks.create(name: "archive${taskSuffix}", type:org.gradle.api.tasks.Copy) {
description "Archive/copy APK and mappings.txt to a versioned folder."
from ("${buildDir}") {
include "**/proguard/${flavor.name}/${variant.buildType.name}/mapping.txt"
include "**/apk/${variant.outputFile.name}"
}
into destination
eachFile { file->
file.path = file.name // so we have a "flat" copy
}
includeEmptyDirs = false
}
tasks[assembleTaskName].finalizedBy = [copyAPKTask]
}
}
}
}
}
def publish = project.tasks.create("publishAll")// publish all task
applicationVariants.all { variant ->
if (variant.buildType.name.equals("release")) {// Only Release
File outDir = file("//192.168.4.11/Android/Release")
File apkFile = variant.outputs[0].outputFile
File mapFile = variant.mappingFile
def task = project.tasks.create("publish${variant.name.capitalize()}Apk", Copy)
task.from apkFile, mapFile
task.into outDir
task.rename "mapping.txt", "${apkFile.name.substring(0, apkFile.name.length() - 3)}mapping.txt"// Rename mapping.txt
task.doLast{
println ">>>publish ${variant.name} success!" +
"/ndir: ${outDir}" +
"/napk: ${apkFile.name}"
}
task.dependsOn variant.assemble
publish.dependsOn task
}
}