Cómo cambiar el nombre de la aplicación por tipo de compilación de Gradle

135

Estoy tratando de encontrar una manera de poder cambiar el nombre de la aplicación de mi aplicación por tipo de compilación en gradle.

Por ejemplo, me gustaría tener la versión de depuración <APP_NAME>-debugy la versión qa tener <APP-NAME>-QA.

Estoy familiarizado con:

debug {
        applicationIdSuffix '.debug'
        versionNameSuffix '-DEBUG'
}

Sin embargo, parece que no puedo encontrar un comando gradle para aplicar el cambio de la aplicación cuando estoy en el iniciador.

Andre Perkins
fuente

Respuestas:

167

Si por "nombre de la aplicación", que quiere decir android:labelen <application>, la solución más sencilla es tener ese punto a un recurso de cadena (por ejemplo, android:label="@string/app_name"), y luego tener una versión diferente de ese recurso de cadena en un src/debug/sourceset.

Se puede ver que en este proyecto de ejemplo , donde tengo un reemplazo para app_nameen src/debug/res/values/strings.xml, que se aplicará para la debugconstruye. releaselas compilaciones usarán la versión de app_namein src/main/.

CommonsWare
fuente
¿No implicaría esta solución que tendríamos que agregar strings.xml extra para cada traducción? eso podría convertirse en un dolor de mantenimiento ...
sfera
77
@sfera: Primero, puede aislar esta cadena en su propio archivo de recursos si lo desea. En segundo lugar, esto es solo para una cadena. En tercer lugar, esto es solo para los tipos de compilación en los que desea reemplazar esa cadena. Cuarto, a menos que tenga un equipo de desarrollo sin un lenguaje común, no necesitará traducir sin releasecadenas.
CommonsWare
Aislar la cuerda suena como una buena idea. ¡Gracias por eso! En cuanto a la no releaseparte, veo que de manera un poco diferente, ya que uno también podría probar los problemas de localización al tiempo que permite que las compilaciones de "lanzamiento" y "prueba" coexistan en el mismo dispositivo. En tal caso, ambas compilaciones pueden terminar con la misma etiqueta de iniciador, lo que probablemente cause cierta confusión. Eso es lo que estaba tratando de evitar.
sfera
1
@sfera: "Eso es lo que estaba tratando de evitar", así que no traduzca esta cadena. La prueba en esa cadena no será válida de todos modos, ya que, por definición, no es la cadena que desea usar en releasemodo. Y solo use este recurso de cadena para app_name, no para ningún otro rol.
CommonsWare
3
@sfera: Nunca enviarás una aplicación con "AppNom-DEBUG". Puede enviar una aplicación con "AppNom". Probar "AppNom-DEBUG", por lo tanto, es innecesario. Sin duda, puede traducir una versión de depuración de app_name, aunque no sea necesario (por ejemplo, tiene desarrolladores franceses o alemanes que no hablan inglés y, por lo tanto, deben traducirlo). Para realizar pruebas para ver si la releaseversión no modificada de las app_nameobras, con sus traducciones, prueba la releasecompilación o crea un near-releasetipo de compilación que solo agrega el sufijo de ID de la aplicación y deja las cadenas en paz.
CommonsWare
159

Puedes usar algo como esto

 buildTypes {
    debug {
        applicationIdSuffix '.debug'
        versionNameSuffix '-DEBUG'
        resValue "string", "app_name", "AppName debug"
    }
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
        zipAlignEnabled true
        resValue "string", "app_name", "AppName"
    }
}

Puede usar @ string / app_name en los archivos AndroidManifest.xml.

Asegúrate de eliminar app_name de los valores / carpeta (ninguna entrada con este nombre).

irscomp
fuente
Perfecto cuando el nombre de la aplicación debe leerse desde un archivo externo
Joe Maher
Obtuve un error al construir de esta manera. Error en la ejecución de la tarea ': aplicación: mergeDebugResources' .. Recursos duplicados: res / values ​​/ strings.xml: string / app_name
user2010496
55
Si obtienes: Obtuve un error al construir de esta manera. Error en la ejecución de la tarea ': aplicación: mergeDebugResources' .. Recursos duplicados: res / values ​​/ strings.xml: string / nombre_aplicación que debe hacer, como está escrito: "Asegúrese de eliminar el nombre_aplicación de los valores / carpeta (ninguna entrada con este nombre ) ".
ivan.panasiuk 05 de
Me gusta esto porque la solución de carpeta de cadenas (la solución aceptada, arriba) solo funciona si el nombre de la aplicación se define para un conjunto de fuentes / sabor de producto en particular. En mi caso, estoy configurando un trabajo de Jenkins Pipeline para crear diferentes versiones de nuestra aplicación automáticamente con diferentes nombres, y no todos esos nombres tienen definidos ProductFlavors para ellos. Entonces Jenkins simplemente proporciona el nombre de la aplicación a través del entorno, y Gradle lo lee:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex
si eliminé nombre_aplicación de la carpeta de cadenas, obtengo un error al compilar el tiempo obteniendo el error -Error: Error de ejecución para la tarea ': aplicación: processDevDebugManifest'. > La fusión manifiesta falló con múltiples errores, ver registros
aj0822ArpitJoshi
55

Puedes hacer esto con gradle:

android {
    buildTypes {
        release {
            manifestPlaceholders = [appName: "My Standard App Name"]
        }
        debug {
            manifestPlaceholders = [appName: "Debug"]
        }
    }
}

Luego en tu AndroidManifest.xmlpuesto:

<application
    android:label="${appName}"/>
    <activity
        android:label="${appName}">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Nota: también funciona con productFlavors.

Albert Vila Calvo
fuente
obteniendo error -Error: la ejecución falló para la tarea ': aplicación: processDevDebugManifest'. > La fusión manifiesta falló con múltiples errores, ver registros
aj0822ArpitJoshi
NO FUNCIONA --- buildTypes {release {minifyEnabled false proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} debug {manifestPlaceholders = [appName: "GridL Debug"] applicationIdSuffix ".dev1"}}
JSONParser
44

Para apoyar las traducciones, haga esto:

1. eliminar la cadena "nombre_aplicación"

2. agregar a gradle

 buildTypes {
    admin {
       resValue "string", "app_name", "@string/app_name_admin"
    }
    release {
        resValue "string", "app_name", "@string/app_name_release"
    }
    debug {
        resValue "string", "app_name", "@string/app_name_debug"
    }
}

3. Establezca el nombre de la aplicación en el Manifiesto como "@ string / app_name"

4. Agregar a valores strings.xml

<string name="app_name_admin">App Admin</string>
<string name="app_name_release">App  release</string>
<string name="app_name_debug">App debug</string>
NickUnuchek
fuente
¿Cuáles son los diferentes tipos de tipos de compilación? ¿Aparte de, admin, lanzamiento y depuración?
Dinesh
@DineshVG puede establecer la diferencia usted mismo, por ejemplo, diferente applicationId
NickUnuchek
Quiero usar la prueba UIAutomator en otra configuración de compilación que no sea la depuración con diferentes reglas pro-guard. Es eso posible ?
Dinesh
Esta debería ser la respuesta aceptada, funcionó muy bien para mí
Oleg Dater
Realmente me gusta este enfoque porque te permite incluso agregar un personalizado app_nameen la sección del archivo productFlavorsbuild.gradle . Un enfoque extremadamente conveniente y flexible cuando lo necesita.
Egel
15

El nombre de la aplicación es visible para el usuario, y es por eso que Google lo alienta a mantenerlo en su archivo strings.xml. Puede definir un archivo de recursos de cadena separado que contenga cadenas que sean específicas para sus buildTypes. Parece que puede tener un qabuildType personalizado . Si eso no es cierto, ignore la parte qa a continuación.

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml
Krylez
fuente
1
¿Esto funcionó alguna vez para ti? Documenté mi ejemplo, y no funciona ... stackoverflow.com/questions/26032950/…
volkersfreunde
estos son sabores, no tipos de construcción
Georgian Benetatos
13

Necesitamos una solución para admitir el nombre de la aplicación con localización (para varios idiomas). He probado con la solución @Nick Unuchek, pero la construcción ha fallado (no se ha encontrado @ string /). un pequeño cambio para solucionar este error: archivo build.gradle:

android {
    ext{
        APP_NAME = "@string/app_name_default"
        APP_NAME_DEV = "@string/app_name_dev"
    }

    productFlavors{

        prod{
            manifestPlaceholders = [ applicationLabel: APP_NAME]
        }

        dev{
            manifestPlaceholders = [ applicationLabel: APP_NAME_DEV ]
        }

    }

valores \ cadenas.xml:

<resources>
    <string name="app_name_default">AAA prod</string>
    <string name="app_name_dev">AAA dev</string>

</resources>

values-en \ strings.xml:

<resources>
    <string name="app_name_default">AAA prod en</string>
    <string name="app_name_dev">AAA dev en</string>

</resources>

Manifest.xml:

<application
    android:label="${applicationLabel}" >
</application>
HungNM2
fuente
Un juego como "Need for Speed", por ejemplo, nunca se llamará "Bedürfnis nach Geschwindigkeit" en Alemania. A menos que sea una estafa de un desarrollador dudoso ...
El increíble Jan
Está funcionando. Muchas gracias. Sin embargo, en mi caso, tengo que añadir 1 más tools:replace="android:label"en applicationenAndroidManifest
Phan Van Linh
5

Para obtener una solución más dinámica basada en gradle (p. Ej., Establezca un nombre de aplicación base en main strings.xmluna vez y evite repetirlo en cada combinación de sabor / compilación strings.xml), vea mi respuesta aquí: https://stackoverflow.com/a/32220436/1128600

Steffen Funke
fuente
2

Puede usar strings.xmlen diferentes carpetas, vea los valores de cadena separados de Android para las versiones de lanzamiento y depuración .

Entonces, crea este archivo:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Your app name</string>
</resources>

Luego péguelo en app\src\debug\res\values\y app\src\release\res\values\carpetas. Reemplace "Su nombre de aplicación" en depurar y liberar archivos. Retire app_nameelemento de strings.xmlen app\src\main\res\values\carpeta.

En AndroidManifestti tendrás lo mismo

<application
    android:label="@string/app_name"
    ...

No hay cambios en absoluto. Incluso si agregó una biblioteca con su AndroidManifestarchivo y strings.xml.

CoolMind
fuente
1

Como el autor pide hacer esto en Gradle , podemos suponer que quiere hacerlo en el script y no en los archivos de configuración. Dado que tanto Android Studio como Gradle se han actualizado y modificado en gran medida en el último año (~ 2018), todas las demás respuestas anteriores parecen demasiado retorcidas. La manera más fácil es agregar lo siguiente a su app/build.gradle:

android {
    ...
    buildTypes {
        ...
        // Rename/Set default APK name prefix (app*.apk --> AwesomeApp*.apk)
        android.applicationVariants.all { variant ->
            variant.outputs.all { output ->
                def appName = "AwesomeApp"
                outputFileName = appName+"-${output.baseName}-${variant.versionName}.apk"
        }
    }
}
not2qubit
fuente