Como alterar o nome do aplicativo por tipo de construção Gradle

135

Estou tentando descobrir uma maneira de alterar o nome do aplicativo do meu aplicativo por tipo de compilação em gradle.

Por exemplo, eu gostaria que a versão de depuração tivesse <APP_NAME>-debuge a versão qa tivesse <APP-NAME>-QA.

Estou familiarizado com:

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

No entanto, não consigo encontrar um comando gradle para aplicar a alteração do aplicativo no iniciador.

Andre Perkins
fonte

Respostas:

167

Se por "nome do aplicativo", você quer dizer android:labelem <application>, a solução mais simples é ter esse ponto em um recurso de cadeia (por exemplo, android:label="@string/app_name"), então tem uma versão diferente do que recurso de cadeia em um src/debug/sourceset.

Você pode ver isso neste projeto de amostra , onde eu tenho um substituto para app_namein src/debug/res/values/strings.xml, que será aplicado para debugcompilações. releasebuilds usará a versão do app_namein src/main/.

CommonsWare
fonte
essa solução não implica que teríamos que adicionar um strings.xml extra para cada tradução? que poderia se tornar uma dor de manter ...
sfera
7
@fera: Primeiro, você pode isolar essa string em seu próprio arquivo de recursos, se desejar. Segundo, isso é apenas para uma string. Terceiro, isso é apenas para os tipos de compilação em que você deseja substituir essa sequência. Quarto, a menos que você tenha uma equipe de desenvolvimento sem um idioma comum, não precisaria traduzir não- releasestrings.
CommonsWare
Isolar a corda parece uma boa ideia. Obrigado por isso! Quanto à releaseparte não , vejo que, de maneira um pouco diferente, também é possível testar problemas de localização, enquanto permite que as compilações "release" e "test" coexistam no mesmo dispositivo. Nesse caso, ambas as compilações podem acabar com o mesmo rótulo do iniciador, provavelmente causando alguma confusão. Era isso que eu estava tentando evitar.
Ssp
1
@sfera: "Era isso que eu estava tentando evitar" - portanto, não traduza essa string. O teste nessa string será inválido de qualquer maneira, pois, por definição, não é a string que você deseja usar no releasemodo. E use apenas esse recurso de cadeia para app_name, não para qualquer outra função.
CommonsWare
3
@sfera: você nunca enviará um aplicativo com "AppNom-DEBUG". Você pode enviar um aplicativo com "AppNom". Testar "AppNom-DEBUG", portanto, é desnecessário. Você certamente pode traduzir uma versão de depuração app_name, mesmo que isso não seja necessário (por exemplo, você tem desenvolvedores franceses ou alemães que não falam inglês e, portanto, precisam traduzi-la). Para testar, verifique se a releaseversão não modificada do app_nametrabalho, com suas traduções, testa a releasecompilação ou cria um near-releasetipo de compilação que apenas adiciona o sufixo de ID do aplicativo e deixa as sequências em paz.
CommonsWare
159

Você pode usar algo como isto

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

Você pode usar @ string / app_name nos arquivos AndroidManifest.xml.

Certifique-se de remover app_name dos valores / pasta (nenhuma entrada com esse nome).

irscomp
fonte
Perfeito quando o nome do aplicativo precisa ser lido de um arquivo externo #
Joe Maher
Ocorreu um erro ao construir desta maneira. Falha na execução da tarefa ': app: mergeDebugResources' .. Recursos duplicados: res / values ​​/ strings.xml: string /
app_name
5
Se você receber: Ocorreu um erro ao criar esse caminho. Falha na execução da tarefa ': app: mergeDebugResources' .. Recursos duplicados: res / values ​​/ strings.xml: string / app_name que você deve executar, como está escrito: "Certifique-se de remover app_name dos valores / pasta (nenhuma entrada com esse nome ). "
Ivan.panasiuk
Gosto disso porque a solução da pasta strings (a solução aceita acima) funciona apenas se o nome do aplicativo estiver definido para um conjunto de fontes / sabor do produto específico. No meu caso, estou configurando um trabalho do Jenkins Pipeline para criar versões diferentes do nosso aplicativo automaticamente com nomes diferentes, e nem todos esses nomes têm productFlavors definidos para eles. Portanto, Jenkins simplesmente fornece o nome do aplicativo por meio do ambiente e gradle o lê:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex
se eu removi app_name da pasta string, obtendo erro em tempo de compilação com erro -Erro: Falha na execução da tarefa ': app: processDevDebugManifest'. > Fusão de manifesto falhou com vários erros, consulte logs
aj0822ArpitJoshi
55

Você pode fazer isso com gradle:

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

Então no seu AndroidManifest.xmlput:

<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: também funciona com productFlavors.

Albert Vila Calvo
fonte
recebendo erro -Erro: Falha na execução da tarefa ': app: processDevDebugManifest'. Falha na fusão do manifesto com vários erros, consulte os logs
aj0822ArpitJoshi
NÃO FUNCIONA --- buildTypes {release {minifyEnabled false proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} depuração {manifestPlaceholders = [appName: "GridL Debug"] applicationIdSuffix ".dev1"}}
JSONParser 17/01/19
44

Para suportar traduções, faça o seguinte:

1. remova a string "app_name"

2. adicionar ao 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. Defina o nome do aplicativo no manifesto como "@ string / app_name"

4. Adicione aos 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
fonte
Quais são os diferentes tipos de tipos de construção? Além de admin, release e depuração?
Dinesh
@DineshVG você pode definir diferença por si mesmo, por exemplo applicationId diferente
NickUnuchek
Eu quero usar o teste UIAutomator em outra configuração de compilação que não seja depuração com diferentes regras pro-guard. Isso é possível ?
Dinesh
Esta deve ser a resposta aceita, funcionou muito bem para mim
Oleg Dater 22/02
Eu realmente gosto dessa abordagem porque ela permite que você adicione um costume app_namena seção do arquivo productFlavorsbuild.gradle . Uma abordagem extremamente conveniente e flexível quando você precisar.
Egel 08/07
15

O nome do aplicativo é visível ao usuário, e é por isso que o Google incentiva você a mantê-lo em seu arquivo strings.xml. Você pode definir um arquivo de recurso de sequência separado que contenha sequências específicas para seus buildTypes. Parece que você pode ter um qabuildType personalizado . Se isso não for verdade, ignore a parte qa abaixo.

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml
Krylez
fonte
1
isso já funcionou para você? Eu documentei o meu exemplo, e ele não funciona ... stackoverflow.com/questions/26032950/…
volkersfreunde
estes são sabores, não tipos de construção
Georgian Benetatos
13

Precisamos de uma solução para oferecer suporte ao nome do aplicativo com localização (para vários idiomas). Eu testei com a solução @Nick Unuchek, mas a construção falhou (não foi encontrado @ string /). uma pequena mudança para corrigir esse erro: arquivo 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 ]
        }

    }

values ​​\ strings.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
fonte
Um jogo como "Need for Speed", por exemplo, nunca será chamado de "Bedürfnis nach Geschwindigkeit" na Alemanha. A menos que seja algum truque de um desenvolvedor duvidoso ...
O incrível Jan
Está funcionando. Muito obrigado. No entanto, no meu caso, eu preciso adicionar 1 mais tools:replace="android:label"em applicationemAndroidManifest
Phan Van Linh
5

Para uma solução baseada em gradle mais dinâmica (por exemplo, defina o nome do aplicativo base em main's strings.xmluma vez e evite repetir-se em cada combinação de tipo de sabor / compilação strings.xml), consulte minha resposta aqui: https://stackoverflow.com/a/32220436/1128600

Steffen Funke
fonte
2

Você pode usar strings.xmlem pastas diferentes. Consulte Valores de sequência separados do Android para versões de lançamento e depuração .

Então, crie este arquivo:

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

Em seguida, cole-o em app\src\debug\res\values\e app\src\release\res\values\pastas. Substitua "O nome do seu aplicativo" nos arquivos de depuração e lançamento. Remover app_nameitem strings.xmlna app\src\main\res\values\pasta.

Em AndroidManifestvocê terá o mesmo

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

Nenhuma alteração. Mesmo se você adicionou uma biblioteca ao seu AndroidManifestarquivo e strings.xml.

CoolMind
fonte
1

Como o autor pede para fazer isso em Gradle , podemos assumir que ele deseja fazê-lo no script e não nos arquivos de configuração. Como o Android Studio e o Gradle foram fortemente atualizados e modificados no ano passado (~ 2018), todas as outras respostas acima parecem excessivamente distorcidas. A maneira mais fácil, é adicionar o seguinte ao seu 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
fonte