¿Cómo proporcionar diferentes íconos de aplicaciones de Android para diferentes tipos de compilación de gradle?

101

Tengo dos tipos de compilación configurados en mi archivo gradle: debugy release. Me gustaría poder configurar un ícono de aplicación diferente para el debugtipo de compilación. ¿Hay alguna forma de hacerlo solo a través del tipo de compilación, sin entrar en sabores de productos? El archivo build.gradle está debajo.

apply plugin: 'android'

//...

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 30
        versionName "2.0"
    }
    buildTypes {
        debug {
            packageNameSuffix '.debug'
            versionNameSuffix '-SNAPSHOT'
        }
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
InsanityOnABun
fuente

Respuestas:

157

Lo averigué. Lo que debe hacer es crear una carpeta src separada llamada debugque contenga los diferentes iconos. Por ejemplo, si el diseño de su proyecto es el siguiente y el icono de su lanzador se llama ic_launcher.png:

[Project Root]
  -[Module]
    -src
      -main
        -res
          -drawable-*
            -ic_launcher.png

Luego, para agregar un ícono separado para el tipo de compilación de depuración, agrega:

[Project Root]
  -[Module]
    -src
      -main
        -res
          -drawable-*
            -ic_launcher.png
      -debug
        -res
          -drawable-*
            -ic_launcher.png

Luego, cuando compile bajo el tipo de compilación de depuración, usará ic_launcher que se encuentra en la carpeta de depuración.

InsanityOnABun
fuente
¿No tuvo que especificar la carpeta de depuración adicional con una declaración sourceSets?
ncoronges
1
@ncoronges No lo hice. Al parecer, dado que la depuración es un tipo de compilación incorporado, el conjunto de fuentes también está incorporado.
InsanityOnABun
1
@Scott Me funciona usando 'depuración' si solo pongo mi ícono en cada carpeta dibujable. Por ejemplo, drawable-mdpi, drawable-hdpi, etc. No necesito ninguno de los otros recursos o código en la carpeta de depuración.
rugiente
2
funciona como un encanto. Solo tuve que copiar todos los directorios de mipmap en la carpeta de depuración
Amit Bhandari
1
¿Cómo tener un nombre de aplicación diferente?
DKV
90

Este es un enfoque útil, aunque tiene una desventaja importante ... ambos lanzadores se colocarán en su apk. - Bartek Lipinski

La mejor manera: la respuesta de InsanityOnABun

AndroidManifest.xml

<manifest 

    ...
        <application
        android:allowBackup="true"
        android:icon="${appIcon}"
        android:roundIcon="${appIconRound}"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    ...

    </application>

</manifest>

build.gradle

android {

    ...
        productFlavors{
        Test{
            versionName "$defaultConfig.versionName" + ".test"
            resValue "string", "app_name", "App-Test"
            manifestPlaceholders = [
                    appIcon: "@mipmap/ic_launcher_test",
                    appIconRound: "@mipmap/ic_launcher_test_round"
            ]
        }

        Product{
            resValue "string", "app_name", "App"
            manifestPlaceholders = [
                    appIcon: "@mipmap/ic_launcher",
                    appIconRound: "@mipmap/ic_launcher_round"
            ]
        }
    }
}

la URL de Github: compile una aplicación de varias versiones con Gradle

qinmiao
fuente
1
Este es un enfoque útil, aunque tiene una desventaja importante ... ambos lanzadores se colocarán en su apk.
Bartek Lipinski
-_- # Es un problema, lo actualizo La mejor manera: -> stackoverflow.com/a/22876224/703225
qinmiao
2
¿Por qué es un inconveniente importante? no me parece demasiado importante, y es una solución gradle buena y limpia
luky
2
Segundo la pregunta de @ luky. ¿Por qué es esto un inconveniente? Creo que agregar directorios de nivel superior adicionales (tengo cuatro variantes de compilación diferentes en mi proyecto) es menos limpio que usar marcadores de posición de manifiesto. Especialmente cuando esos directorios contienen solo un ícono.
GregSantulli
Si desea usar de esta manera y dejar de agregar ambos íconos al APK de producción, puede establecer el manifestPlaceholdersúnico en la fase de ejecución o detrás de una ifdeclaración. Estoy haciendo esto porque tengo 1 tipo de compilación que no es de producción que puede tener dos íconos diferentes (y no quiero tener un tipo de compilación completo con solo 1 diferencia con el otro)
Nahuel Barrios
11

También puede especificar el icono en el archivo parcial AndroidManifest.xml del tipo de producto:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">
    <application
        tools:replace="android:icon"
        android:icon="@drawable/alternative_icon" />
</manifest>

Esto sobrescribirá el icono que especifique en el archivo AndroidManifest.xml original.

isyi
fuente
4
Comprueba la pregunta. "¿Hay alguna forma de hacer esto simplemente a través del tipo de construcción, sin entrar en sabores de productos ?"
InsanityOnABun
4
Si bien no fue como se le pidió, ¡me ayudó mucho! ~ usando sabores ~
Flummox - Don't be evil SE
2
La mejor manera de hacerlo, si ya tiene archivos de manifiesto específicos de cada sabor.
Zax
Esta es la única solución que he visto hasta ahora donde puede mantener nombres únicos para los íconos del iniciador ... en lugar de tener más de 10 versiones de ic_launcher.png, tener que saber cuál es cuál solo por dónde está ubicado o abrirlo realmente (no es así bonito). No sabía que este tipo de extensión para el archivo de manifiesto fuera posible, no lo he visto mencionado en ningún otro lugar en SO o de otra manera antes aquí. Elegante sin duda
Gene Bo
6

Para obtener diferentes íconos mientras usa diferentes sabores con múltiples dimensiones, como:

flavorDimensions "color", "size"
productFlavors {
    black {
        dimension "color"
    }
    white {
        dimension "color"
    }

    big {
        dimension "size"
    }
    small {
        dimension "size"
    }
}

Esto se puede lograr como:

Primero, coloque los recursos de depuración en carpetas separadas, como:

src/blackDebug/res
src/whiteDebug/res

En segundo lugar, poner la clave con múltiples dimensiones de sabor es que el nombre del conjunto de fuentes debe contener todas las posibles combinaciones de sabor, incluso si algunas de estas dimensiones no afectan al icono.

sourceSets {
    // Override the icons in debug mode
    blackBigDebug.res.srcDir 'src/blackDebug/res'
    blackSmallDebug.res.srcDir 'src/blackDebug/res'
    whiteBigDebug.res.srcDir 'src/whiteDebug/res'
    whiteSamllDebug.res.srcDir 'src/whiteDebug/res'
}

Para que quede claro, lo siguiente no funcionará cuando se utilicen varias dimensiones:

sourceSets {
    // Override the icons in debug mode
    blackDebug.res.srcDir 'src/blackDebug/res'
    whiteDebug.res.srcDir 'src/whiteDebug/res'
}
Jose gómez
fuente
No estoy seguro de cómo ayudaría esto, ya que el icono de inicio está declarado en el archivo de manifiesto. ¿Puede abordar ese problema?
David Rector
3
El nombre del recurso se declara en el manifiesto, pero puede tener diferentes íconos con los mismos nombres de archivo en diferentes carpetas específicas de sabor como se describe en mi publicación.
Jose Gómez
0

Solución paso a paso, que incluye reemplazar mipmap-anydpi-v26 y mantener archivos para todas las dimensiones:

Primero defina en build.gradle (Módulo: aplicación) su tipo de compilación en Android -> buildTypes -> debug, internal, etc.

En la jerarquía del proyecto, debajo de Android, haga clic derecho en la aplicación -> Nuevo -> Activo de imagen -> en Ruta elija su ícono -> cualquier otro cambio en Capa de fondo y Legado -> Siguiente -> en Directorio de Res elija el tipo de compilación deseado ( debug, internal, main, etc) -> Finalizar

De esa manera, los íconos reemplazarán todos los íconos antiguos que tenía.

Robert Pal
fuente