Comment fournir différentes icônes d'applications Android pour différents types de construction de gradle?

101

J'ai deux types de build définis dans mon fichier gradle: debuget release. Je voudrais pouvoir définir une icône d'application différente pour le debugtype de construction. Existe-t-il un moyen d'y parvenir uniquement via le type de construction, sans entrer dans les saveurs du produit? Le fichier build.gradle est ci-dessous.

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'])
}
Folie
la source

Réponses:

158

Deviner. Ce que vous devez faire est de créer un dossier src distinct appelé debugqui contient les différentes icônes. Par exemple, si la disposition de votre projet est la suivante et que l'icône de votre lanceur est appelée ic_launcher.png:

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

Ensuite, pour ajouter une icône distincte pour le type de build de débogage, vous ajoutez:

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

Ensuite, lorsque vous construisez sous le type de build debug, il utilisera le ic_launcher trouvé dans le dossier debug.

Folie
la source
N'avez-vous pas eu à spécifier le dossier de débogage supplémentaire avec une déclaration sourceSets?
ncoronges
1
@ncoronges je ne l'ai pas fait. Il semblerait que le débogage soit un type de construction intégré, le jeu de sources pour celui-ci est également intégré.
InsanityOnABun
1
@Scott Cela fonctionne pour moi en utilisant 'debug' si je viens de mettre mon icône dans chaque dossier pouvant être dessiné. Par exemple, drawable-mdpi, drawable-hdpi, etc. Je n'ai besoin d'aucune des autres ressources ou du code dans le dossier de débogage.
roarster le
2
fonctionne comme du charme. Juste eu à copier tous les répertoires mipmap dans le dossier de débogage
Amit Bhandari
1
Comment avoir un nom d'application différent?
DKV
92

C'est une approche pratique bien qu'elle présente un inconvénient important ... les deux lanceurs seront placés dans votre apk. - Bartek Lipinski

La meilleure façon: la réponse 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"
            ]
        }
    }
}

l'url Github: créer une application multi-version avec Gradle

qinmiao
la source
1
C'est une approche pratique bien qu'elle présente un inconvénient important ... les deux lanceurs seront placés dans votre apk.
Bartek Lipinski
-_- # C'est un problème, je le mets à jour.La meilleure façon: -> stackoverflow.com/a/22876224/703225
qinmiao
2
pourquoi est-ce un inconvénient important? cela ne me semble pas trop important, et c'est une bonne et propre solution
gradle
2
Je seconde la question de @ luky. Pourquoi est-ce un inconvénient? Je pense que l'ajout de répertoires de premier niveau supplémentaires (j'ai quatre variantes de construction différentes dans mon projet) est moins propre que l'utilisation d'espaces réservés de manifeste. Surtout lorsque ces répertoires ne contiennent qu'une seule icône.
GregSantulli
Si vous souhaitez utiliser cette méthode et arrêter d'ajouter les deux icônes à l'APK de production, vous pouvez définir le manifestPlaceholdersseul dans la phase d'exécution ou derrière l' ifinstruction et . Je fais cela parce que j'ai 1 type de construction non-production qui peut avoir deux icônes différentes (et je ne veux pas avoir un type de construction entier avec seulement 1 différence avec l'autre)
Nahuel Barrios
12

Vous pouvez également spécifier l'icône dans le fichier partiel AndroidManifest.xml de la saveur du produit:

<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>

Cela écrasera l'icône que vous spécifiez dans le fichier AndroidManifest.xml d'origine

isyi
la source
4
Vérifiez la question. "Y a-t-il un moyen d'y parvenir uniquement via le type de construction, sans entrer dans les saveurs du produit ?"
InsanityOnABun
4
Bien que pas comme demandé, cela m'a beaucoup aidé! ~ en utilisant des saveurs ~
Flummox - Don't be evil SE
2
La meilleure façon de le faire, si vous avez déjà des fichiers manifestes spécifiques à une saveur.
Zax
C'est la seule solution que j'ai vue jusqu'à présent où vous pouvez conserver des noms uniques pour les icônes du lanceur .. vs avoir plus de 10 versions de ic_launcher.png, avoir à savoir laquelle est laquelle uniquement par où elle se trouve ou en l'ouvrant réellement (pas si agréable). Je ne savais pas que ce type d' extension pour le fichier manifeste était même possible, je ne l'ai pas vu mentionné ailleurs sur SO ou autrement avant ici. Élégant à coup sûr
Gene Bo
6

Pour obtenir différentes icônes tout en utilisant différentes saveurs avec plusieurs dimensions, telles que:

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

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

Ceci peut être réalisé comme:

Tout d'abord, placez les ressources de débogage dans des dossiers séparés, tels que:

src/blackDebug/res
src/whiteDebug/res

Deuxièmement, la clé avec plusieurs dimensions de saveur est que le nom de l'ensemble de sources doit contenir toutes les combinaisons de saveurs possibles, même si certaines de ces dimensions n'affectent pas l'icône.

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'
}

Pour être clair, ce qui suit ne fonctionnera pas lorsque plusieurs dimensions sont utilisées:

sourceSets {
    // Override the icons in debug mode
    blackDebug.res.srcDir 'src/blackDebug/res'
    whiteDebug.res.srcDir 'src/whiteDebug/res'
}
José Gómez
la source
Je ne sais pas comment cela aiderait puisque l'icône de lancement est déclarée dans le fichier manifeste. Pouvez-vous résoudre ce problème?
David Rector
3
Le nom de la ressource est déclaré dans le manifeste, mais vous pouvez avoir différentes icônes avec les mêmes noms de fichiers dans différents dossiers spécifiques à la saveur, comme décrit dans mon article.
José Gómez
0

Solution étape par étape, y compris le remplacement de mipmap-anydpi-v26 et la conservation des fichiers pour toutes les dimensions:

Définissez d'abord dans build.gradle (Module: app) votre type de build dans android -> buildTypes -> debug, internal, etc.

Dans la hiérarchie du projet, sous Android, cliquez avec le bouton droit sur l'application -> Nouveau -> Image Asset -> dans Chemin, choisissez votre icône -> toute autre modification sur la couche d'arrière-plan et l'héritage -> Suivant -> dans Res Directory, choisissez le type de construction souhaité ( debug, interne, principal, etc.) -> Terminer

De cette façon, les icônes remplaceront chaque ancienne icône que vous aviez.

Robert Pal
la source