Como fornecer diferentes ícones de aplicativos Android para diferentes buildTypes do gradle?

100

Tenho dois tipos de compilação definidos no meu arquivo gradle: debuge release. Eu gostaria de poder definir um ícone de aplicativo diferente para o debugtipo de compilação. Existe alguma maneira de fazer isso apenas por meio do tipo de compilação, sem entrar em variações de produtos? O arquivo build.gradle está abaixo.

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
fonte

Respostas:

156

Descobri isso. O que você precisa fazer é criar uma pasta src separada chamada debugque contém os diferentes ícones. Por exemplo, se o layout do seu projeto for o seguinte e o ícone do iniciador for chamado ic_launcher.png:

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

Em seguida, para adicionar um ícone separado para o tipo de compilação de depuração, você adiciona:

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

Então, quando você compilar sob o tipo de compilação de depuração, ele usará o ic_launcher encontrado na pasta de depuração.

InsanityOnABun
fonte
Você não precisou especificar a pasta de depuração adicional com uma declaração sourceSets?
ncoronges
1
@ncoronges, não. Parece que, uma vez que a depuração é um tipo de compilação integrado, o conjunto de origem para ele também é integrado.
InsanityOnABun
1
@Scott Funciona para mim usando 'debug' se eu apenas colocar meu ícone em cada pasta drawable. Por exemplo, drawable-mdpi, drawable-hdpi etc. Não preciso de nenhum dos outros recursos ou código na pasta de depuração.
roarster de
2
funciona como charme. Só tive que copiar todos os diretórios do mipmap na pasta de depuração
Amit Bhandari,
1
Como ter um nome de aplicativo diferente?
DKV
90

Esta é uma abordagem útil, embora tenha uma desvantagem importante ... ambos os iniciadores serão colocados em seu apk. - Bartek Lipinski

A melhor maneira: a resposta 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"
            ]
        }
    }
}

o URL do Github: Crie um aplicativo com várias versões com Gradle

qinmiao
fonte
1
Esta é uma abordagem útil, embora tenha uma desvantagem importante ... ambos os iniciadores serão colocados em seu apk.
Bartek Lipinski
-_- # É um problema, eu o atualizo. Da melhor maneira: -> stackoverflow.com/a/22876224/703225
qinmiao
2
porque é uma desvantagem importante? não parece muito importante para mim e é uma solução gradle boa e limpa
luky,
2
Eu concordo com a pergunta de @luky. Por que isso é uma desvantagem? Eu acho que adicionar diretórios de nível superior adicionais (tenho quatro variantes de construção diferentes em meu projeto) é menos claro do que usar marcadores de manifesto. Especialmente quando esses diretórios contêm apenas um único ícone.
GregSantulli
Se quiser usar dessa forma e parar de adicionar os dois ícones ao APK de produção, você pode definir o manifestPlaceholders apenas na fase de execução ou por trás da ifinstrução. Estou fazendo isso porque tenho 1 tipo de construção de não produção que pode ter dois ícones diferentes (e não quero ter um tipo de construção inteiro com apenas 1 diferença com o outro)
Nahuel Barrios
11

Você também pode especificar o ícone no arquivo parcial AndroidManifest.xml da variação do produto:

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

Isso substituirá o ícone que você especificar no AndroidManifest.xml original

isyi
fonte
4
Verifique a pergunta. "Existe alguma maneira de fazer isso apenas por meio do tipo de construção, sem entrar em sabores de produtos ?"
InsanityOnABun
4
Embora não seja como solicitado, me ajudou muito! ~ usando sabores ~
Flummox - não seja mau SE
2
A melhor maneira de fazer isso, se você já tiver arquivos de manifesto específicos de sabor.
Zax
Esta é a única solução que vi até agora em que você pode manter nomes exclusivos para os ícones do iniciador .. em vez de ter mais de 10 versões de ic_launcher.png, ter que saber qual é qual apenas por onde está localizado ou realmente abri-lo (nem tanto legais). Eu não sabia que esse tipo de extensão para o arquivo de manifesto era possível, não vi isso mencionado em nenhum outro lugar no SO ou de outra forma antes aqui. Elegante, com certeza
Gene Bo
6

Para obter ícones diferentes ao usar sabores diferentes com dimensões múltiplas, como:

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

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

Isso pode ser alcançado como:

Primeiro, coloque os recursos de depuração em pastas separadas, como:

src/blackDebug/res
src/whiteDebug/res

Em segundo lugar, a chave com várias dimensões de sabor é que o nome do conjunto de fontes deve conter todas as combinações de sabor possíveis, mesmo que algumas dessas dimensões não afetem o ícone.

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

Apenas para deixar claro, o seguinte não funcionará quando várias dimensões estiverem em uso:

sourceSets {
    // Override the icons in debug mode
    blackDebug.res.srcDir 'src/blackDebug/res'
    whiteDebug.res.srcDir 'src/whiteDebug/res'
}
Jose Gómez
fonte
Não tenho certeza de como isso ajudaria, já que o ícone de inicialização é declarado no arquivo de manifesto. Você pode resolver esse problema?
David Rector
3
O nome do recurso é declarado no manifesto, mas você pode ter ícones diferentes com os mesmos nomes de arquivo em pastas específicas de diferentes sabores, conforme descrito em minha postagem.
Jose Gómez
0

Solução passo a passo, incluindo a substituição de mipmap-anydpi-v26 e manutenção de arquivos para todas as dimensões:

Primeiro defina em build.gradle (Módulo: app) seu tipo de compilação em android -> buildTypes -> debug, interno, etc

Na hierarquia do projeto, abaixo do Android, clique com o botão direito do mouse em aplicativo -> Novo -> Ativo de imagem -> no Caminho, escolha o ícone -> quaisquer outras alterações na Camada de fundo e Legado -> Próximo -> no Diretório Res escolha o tipo de compilação desejado ( debug, internal, main, etc) -> Finish

Dessa forma, os ícones substituirão todos os ícones antigos que você tinha.

Robert Pal
fonte