¿Cómo configurar versionName en APK filename usando gradle?


Estoy intentando establecer un número de versión específico en el nombre de archivo APK generado automáticamente por gradle.

Ahora gradle genera myapp-release.apk pero quiero que se vea algo como myapp-release-1.0.apk.

He intentado cambiar el nombre de las opciones que parece desordenado. ¿Hay una manera sencilla de hacer esto?

buildTypes {
    release {
       signingConfig signingConfigs.release
       applicationVariants.each { variant ->
       def file = variant.outputFile
       variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    defaultConfig.versionName + ".apk"))
    }
}

He probado el código anterior sin suerte. Alguna sugerencia? (usando gradle 1.6)

Author: GR Envoy, 2013-08-20

14 answers

Solo tengo que cambiar el nombre de la versión en un solo lugar. El código también es simple.

Los siguientes ejemplos crearán archivos apk llamados named MyCompany-MyAppName-1.4.8-debug.apk or MyCompany-MyAppName-1.4.8-release.apk dependiendo de la variante de compilación seleccionada.

Consulta también: Cómo cambiar el nombre del archivo de asignación proguard en el proyecto gradle para Android

Solución para el complemento Gradle Reciente

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName")
    }
}

La solución anterior ha sido probada con las siguientes versiones de Android Gradle Plugin:

  • 3.1.0 (marzo de 2018)
  • 3.0.1 (noviembre de 2017)
  • 3.0.0 (octubre de 2017)
  • 2.3.2 (mayo de 2017)
  • 2.3.1 (abril de 2017)
  • 2.3.0 (febrero de 2017)
  • 2.2.3 (diciembre de 2016)
  • 2.2.2
  • 2.2.0 (Septiembre de 2016)
  • 2.1.3 (Agosto de 2016)
  • 2.1.2
  • 2.0.0 (abril de 2016)
  • 1.5.0 (2015/11/12)
  • 1.4.0-beta6 (2015/10/05)
  • 1.3.1 (2015/08/11)

Actualizaré este post a medida que salgan nuevas versiones.

Solución Probada Solo en las versiones 1.1.3-1.3.0

La siguiente solución se ha probado con las siguientes versiones de Android Gradle Plugin:

Archivo de aplicación gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        archivesBaseName = "MyCompany-MyAppName-$versionName"
    }
}
 178
Author: Jon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-26 22:51:35

Esto resolvió mi problema: usando applicationVariants.all en lugar de applicationVariants.each

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk")) 
        }
    }       
}

Actualización:

Así que parece que esto no funciona con versiones 0.14+ de android studio gradle plugin.

Esto hace el truco (Referencia de esta pregunta ) :

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
        }
    }
}
 167
Author: codaR0y,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:33

(EDITADO para trabajar con Android Studio 3.0 y Gradle 4)

Estaba buscando una opción de cambio de nombre de archivo apk más compleja y escribí esta con la esperanza de que sea útil para cualquier otra persona. Cambia el nombre del apk con los siguientes datos:

  • sabor
  • tipo de construcción
  • versión
  • fecha

Me llevó un poco de investigación en las clases de gradle y un poco de copiar/pegar de otras respuestas. Yo he utilizado gradle 3.1.3.

En la compilación.gradle:

android {

    ...

    buildTypes {
        release {
            minifyEnabled true
            ...
        }
        debug {
            minifyEnabled false
        }
    }

    productFlavors {
        prod {
            applicationId "com.feraguiba.myproject"
            versionCode 3
            versionName "1.2.0"
        }
        dev {
            applicationId "com.feraguiba.myproject.dev"
            versionCode 15
            versionName "1.3.6"
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def project = "myProject"
            def SEP = "_"
            def flavor = variant.productFlavors[0].name
            def buildType = variant.variantData.variantConfiguration.buildType.name
            def version = variant.versionName
            def date = new Date();
            def formattedDate = date.format('ddMMyy_HHmm')

            def newApkName = project + SEP + flavor + SEP + buildType + SEP + version + SEP + formattedDate + ".apk"

            outputFileName = new File(newApkName)
        }
    }
}

Si compila hoy (13-10-2016) a las 10: 47, obtendrá los siguientes nombres de archivo dependiendo del tipo y tipo de compilación que haya elegido:

  • dev debug : myProject_ dev_debug_1.3.6_131016_1047.apk
  • dev release : myProject_ dev_release_1.3.6_131016_1047.apk
  • prod debug : myProject_ prod_debug_1.2.0_131016_1047.apk
  • prod release : myProject_ prod_release_1.2.0_131016_1047.apk

Nota: el nombre apk de la versión no alineada sigue siendo el predeterminado.

 31
Author: Fer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-14 09:41:39

Si no especificas versionName en el bloque defaultConfig entonces defaultConfig.versionName resultará en null

Para obtener el nombre de la versión del manifiesto, puede escribir el siguiente código en build.gradle:

import com.android.builder.DefaultManifestParser

def manifestParser = new DefaultManifestParser()
println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
 17
Author: Arkadiusz Konior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-16 14:28:18

Para resumir, para aquellos que no saben cómo importar paquetes en build.gradle (como yo), use lo siguiente buildTypes,

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            def manifestParser = new com.android.builder.core.DefaultManifestParser()
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile) + ".apk")) 
        }
    }       
}

===== EDIT =====

Si pones tu versionCode y versionName en tu archivo build.gradle así:

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 19
    versionCode 1
    versionName "1.0.0"
}

Deberías ponerlo así: {[12]]}

buildTypes {   
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                def file = variant.outputFile
                variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
            }
        }
}


====== EDITAR con Android Studio 1.0 ======

Si está utilizando Android Studio 1.0, obtendrá un error como este:

Error:(78, 0) Could not find property 'outputFile' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated@67e7625f.

Debes cambiar la parte build.Types a esto:

buildTypes {
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
                }
            }
        }
    }
 17
Author: Wesley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-09 03:13:01

En mi caso, solo quería encontrar una manera de automatizar la generación de diferentes apk nombre para release y debug variantes. Me las arreglé para hacer esto fácilmente poniendo este fragmento como un hijo de android:

applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def appName = "My_nice_name_"
        def buildType = variant.variantData.variantConfiguration.buildType.name
        def newName
        if (buildType == 'debug'){
            newName = "${appName}${defaultConfig.versionName}_dbg.apk"
        } else {
            newName = "${appName}${defaultConfig.versionName}_prd.apk"
        }
        output.outputFile = new File(output.outputFile.parent, newName)
    }
}

Para el nuevo Android gradle plugin 3.0.0 se puede hacer algo así:

 applicationVariants.all { variant ->
    variant.outputs.all {
        def appName = "My_nice_name_"
        def buildType = variant.variantData.variantConfiguration.buildType.name
        def newName
        if (buildType == 'debug'){
            newName = "${appName}${defaultConfig.versionName}_dbg.apk"
        } else {
            newName = "${appName}${defaultConfig.versionName}_prd.apk"
        }
        outputFileName = newName
    }
}

Esto produce algo como: My_nice_name_3.2.31_dbg.apk

 7
Author: yshahak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-15 07:10:27

Otra alternativa es usar lo siguiente:

String APK_NAME = "appname"
int VERSION_CODE = 1
String VERSION_NAME = "1.0.0"

project.archivesBaseName = APK_NAME + "-" + VERSION_NAME;

    android {
      compileSdkVersion 21
      buildToolsVersion "21.1.1"

      defaultConfig {
        applicationId "com.myapp"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode VERSION_CODE
        versionName VERSION_NAME
      }

       .... // Rest of your config
}

Esto establecerá "appname-1.0.0" a todas sus salidas apk.

 5
Author: Marco RS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-22 16:50:48

Gradle 4

La sintaxis ha cambiado un poco en Gradle 4 (Android Studio 3+) (de output.outputFile a outputFileName, idea de esta respuesta es ahora:

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def newName = outputFileName
            newName.replace(".apk", "-${variant.versionName}.apk")
            outputFileName = new File(newName)
        }
    }
}
 5
Author: PHPirate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-10 16:36:18

Hay muchas respuestas que son correctas, ya sea en su totalidad o después de algunas modificaciones. Pero voy a agregar el mío de todos modos ya que estaba teniendo el problema con todos ellos porque estaba usando scripts para generar versionName y versionCode dinámicamente conectándome a la tarea preBuild.

Si está utilizando algún enfoque similar, este es el código que funcionará:

project.android.applicationVariants.all { variant ->
    variant.preBuild.doLast {
    variant.outputs.each { output ->
        output.outputFile = new File(
                output.outputFile.parent,
                output.outputFile.name.replace(".apk", "-${variant.versionName}@${variant.versionCode}.apk"))
        }
    }
}

Para explicar: Ya que estoy sobreescribiendo el código de la versión y el nombre en la primera acción de preBuild Tengo que agregar el archivo cambiar el nombre al final de esta tarea. Entonces, lo que gradle hará en este caso es:

Inyectar código de versión / nombre - > hacer acciones precompiladas - > reemplazar nombre para apk

 3
Author: PSIXO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-16 06:13:09

La forma correcta de renombrar apk, según @Jon answer

defaultConfig {
        applicationId "com.irisvision.patientapp"
        minSdkVersion 24
        targetSdkVersion 22
        versionCode 2  // increment with every release
        versionName "0.2" // change with every release
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //add this line
        archivesBaseName = "AppName-${versionName}-${new Date().format('yyMMdd')}"
    }   

U otra forma de lograr los mismos resultados con

android {
    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def formattedDate = new Date().format('yyMMdd')
            outputFileName = "${outputFileName.replace(".apk","")}-v${defaultConfig.versionCode}-${formattedDate}.apk"
        }
    }
}
 3
Author: Qamar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-11 15:00:15
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
        }
    }
 2
Author: timeon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-17 19:14:28

En mi caso resuelvo este error de esta manera

Agregar un SUFIJO a la versión de depuración, en este caso agrego el texto "-DEBUG" a mi deploy de depuración

 buildTypes {
        release {

            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'


        }
        debug {

            defaultConfig {
                debuggable true

                versionNameSuffix "-DEBUG"
            }
        }
    }
 1
Author: exequielc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-05 12:10:44

Para las últimas versiones de gradle puedes usar el siguiente fragmento de código:

Establezca primero la ubicación del manifiesto de su aplicación

 sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
        {
    }

Y más adelante en build.gradle

import com.android.builder.core.DefaultManifestParser

def getVersionName(manifestFile) {
    def manifestParser = new DefaultManifestParser();
    return manifestParser.getVersionName(manifestFile);
}

def manifestFile = file(android.sourceSets.main.manifest.srcFile);
def version = getVersionName(manifestFile)

buildTypes {
    release {
       signingConfig signingConfigs.release
       applicationVariants.each { variant ->
       def file = variant.outputFile
       variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    versionName + ".apk"))
    }
}

Ajuste si tiene diferentes manifiestos por tipo de compilación. pero ya que tengo el único-funciona perfectamente para mí.

 0
Author: Alfishe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-22 03:35:12

A partir de Android Studio 1.1.0, encontré que esta combinación funcionaba en el android cuerpo del archivo build.gradle. Esto es si no puede averiguar cómo importar los datos del archivo xml del manifiesto. Me gustaría que fuera más compatible con Android Studio, pero solo juegue con los valores hasta que obtenga la salida del nombre APK deseado:

defaultConfig {
        applicationId "com.package.name"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 6
        versionName "2"
    }
    signingConfigs {
        release {
            keyAlias = "your key name"
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            signingConfig signingConfigs.release
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace("app-release.apk", "appName_" + versionName + ".apk"))
                }
            }
        }
    }
 0
Author: A13X,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 20:40:12