Как изменить имя приложения для каждого типа сборки Gradle

135

Я пытаюсь найти способ изменить имя приложения моего приложения для каждого типа сборки в gradle.

Например, я хотел бы иметь версию отладки и версию <APP_NAME>-debugqa <APP-NAME>-QA.

Я знаком с:

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

Однако я не могу найти команду gradle для применения изменения приложения, когда оно находится в панели запуска.

Андре Перкинс
источник

Ответы:

167

Если под "названием приложения" вы имеете в виду android:label на <application>, самое простое решение , чтобы иметь эту точку струнный ресурса (например, android:label="@string/app_name"), то есть другая версия этой строки ресурса в src/debug/sourceset.

Вы можете видеть это в этом примере проекта , где у меня есть замена для app_namein src/debug/res/values/strings.xml, которая будет применяться для debugсборок. releaseсборки будут использовать версию app_namein src/main/.

CommonsWare
источник
Разве это решение не подразумевает, что нам придется добавлять дополнительный strings.xml для каждого перевода? это может стать
проблемой
7
@sfera: Во-первых, вы можете изолировать эту строку в ее собственном файле ресурсов, если хотите. Во-вторых, это только для одной строки. В-третьих, это только для типов сборки, где вы хотите заменить эту строку. В-четвертых, если у вас нет команды разработчиков без единого языка, вам не нужно переводить нестроковые releaseстроки.
CommonsWare
Изолировать строку звучит как хорошая идея. Спасибо за это! Что касается «не- releaseчасти», я вижу, что это немного по-другому, так как можно было бы также протестировать на наличие проблем с локализацией, позволяя «релизной» и «тестовой» сборкам сосуществовать на одном устройстве. В таком случае обе сборки могут иметь одинаковую метку запуска, что, вероятно, вызовет некоторую путаницу. Это то, чего я пытался избежать.
Сфера
1
@sfera: «Это то, чего я пытался избежать» - так что не переводите эту строку. Тест для этой строки в любом случае будет недействительным, поскольку по определению это не та строка, которую вы хотите использовать в releaseрежиме. И используйте этот строковый ресурс app_nameтолько для других ролей.
CommonsWare
3
@sfera: вы никогда не отправите приложение с «AppNom-DEBUG». Вы можете отправить приложение с «AppNom». Тестирование «AppNom-DEBUG», следовательно, не нужно. Вы, безусловно, можете перевести отладочную версию app_name, даже если в этом нет необходимости (например, у вас есть французские или немецкие разработчики, которые не говорят по-английски и, следовательно, нуждаются в переводе). Чтобы проверить, работает ли немодифицированная releaseверсия app_nameс ее переводами, протестируйте releaseсборку или создайте near-releaseтип сборки, который просто добавляет суффикс идентификатора приложения и оставляет строки в покое.
CommonsWare
159

Вы можете использовать что-то вроде этого

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

Вы можете использовать @ string / app_name в файлах AndroidManifest.xml.

Убедитесь, что вы удалили app_name из values ​​/ folder (нет записи под этим именем).

irscomp
источник
Идеально, когда имя приложения нужно прочитать из внешнего файла
Джо Махер
Получил ошибку при построении таким образом. Ошибка выполнения для задачи ': app: mergeDebugResources' .. Дублирующиеся ресурсы: res / values ​​/ strings.xml: string / app_name
user2010496
5
Если вы получили: Получил ошибку при построении таким образом. Выполнение не выполнено для задачи ': app: mergeDebugResources' .. Дублирующиеся ресурсы: res / values ​​/ strings.xml: string / app_name, которые вы должны сделать, как написано: "Убедитесь, что вы удалили app_name из значений / папки (нет записи с этим именем ) «.
ivan.panasiuk 05
Мне это нравится, потому что решение для папки строк (принятое решение, приведенное выше) работает только в том случае, если имя приложения определено для определенного исходного набора / вкуса продукта. В моем случае я настраиваю задание Jenkins Pipeline для автоматического создания разных версий нашего приложения с разными именами, и не для всех этих имен определены productFlavors. Таким образом, Дженкинс просто передает имя приложения через среду, а gradle читает его:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex,
если я удалил app_name из строковой папки, то получаю ошибку времени компиляции, получая ошибку -Error: Execution failed for task ': app: processDevDebugManifest'. > Манифест слияния
завершился
55

Вы можете сделать это с помощью gradle:

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

Затем в вашем AndroidManifest.xmlвводе:

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

Примечание: он также работает с productFlavors.

Альберт Вила Кальво
источник
получение ошибки -Error: Выполнение не удалось для задачи ': app: processDevDebugManifest'. > Слияние манифестов с множественными ошибками, см. Журналы
aj0822ArpitJoshi
НЕ РАБОТАЕТ --- buildTypes {release {minifyEnabled false proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} отладка {manifestPlaceholder = [appName: "GridL Debug"] applicationIdSuffix ".dev1"}}
JSONParser
44

Для поддержки переводов сделайте это:

1. удалить строку "app_name"

2. добавить в 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. Установите имя приложения в манифесте как "@ string / app_name"

4. Добавьте в 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
источник
Какие бывают типы сборки? Кроме, админ, релиз и отладка?
Динеш
@DineshVG вы можете установить разницу самостоятельно, например, разные applicationId
NickUnuchek
Я хочу использовать тест UIAutomator в другой конфигурации сборки, кроме отладки с другими правилами pro-guard. Это возможно ?
Динеш
Это должен быть принятый ответ, отлично сработал для меня
Олег Датер
Мне очень нравится этот подход , поскольку он позволяет даже добавить обычай app_nameв productFlavors части build.gradleфайла. Чрезвычайно удобный и гибкий подход, когда вам это нужно.
Эгель
15

Название приложения видно пользователю, поэтому Google рекомендует вам сохранить его в файле strings.xml. Вы можете определить отдельный файл строкового ресурса, который содержит строки, специфичные для ваших типов сборки. Похоже, у вас может быть собственный qabuildType. Если это не так, проигнорируйте часть qa ниже.

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml
Krylez
источник
1
это когда-нибудь работало для вас? Я задокументировал свой пример, и он не работает ... stackoverflow.com/questions/26032950/…
volkersfreunde
это ароматы, а не типы сборки
Georgian Benetatos
13

Нам нужно решение для поддержки имени приложения с локализацией (для мультиязычности). Я тестировал решение @Nick Unuchek, но сборка не удалась (не найдено @ string /). небольшое изменение, чтобы исправить эту ошибку: файл 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 ]
        }

    }

значения \ strings.xml:

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

</resources>

Значения-ан \ 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
источник
Например, такая игра, как «Need for Speed», никогда не будет называться «Bedürfnis nach Geschwindigkeit» в Германии. Если это не мошенничество со стороны сомнительного разработчика ...
Невероятное
Это работает. Огромное спасибо. Тем не менее, в моем случае, мне нужно добавить еще 1 tools:replace="android:label"в applicationвAndroidManifest
Фан Ван Linh
5

Для более динамичного решения на основе Gradle (например, установите базовое имя приложения в main strings.xmlодин раз и избегайте повторения в каждой комбинации типа / типа сборки strings.xml), см. Мой ответ здесь: https://stackoverflow.com/a/32220436/1128600

Штеффен Функе
источник
2

Вы можете использовать strings.xmlв разных папках, увидеть Android отдельные строковые значения для выпуска и отладки сборки .

Итак, создайте этот файл:

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

Затем вставьте его app\src\debug\res\values\и app\src\release\res\values\папки. Замените «Имя вашего приложения» в файлах отладки и выпуска. Удалить app_nameэлемент из strings.xmlвapp\src\main\res\values\ папке.

У AndroidManifestвас будет то же самое

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

Никаких изменений. Даже если вы добавили библиотеку с ее AndroidManifestфайлом и strings.xml.

CoolMind
источник
1

Поскольку автор просит сделать это в Gradle , мы можем предположить, что он хочет сделать это в сценарии, а не в файлах конфигурации. Поскольку и Android Studio, и Gradle были сильно обновлены и изменены в прошлом году (~ 2018), все остальные ответы выше кажутся чрезмерно искаженными. Самый простой способ - добавить в ваш 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
источник