如何根据Gradle构建类型更改应用程序名称

177

我正在努力找到一种方法,可以在gradle的每个构建类型中更改我的应用程序名称。

例如,我希望调试版本的名称为<APP_NAME>-debug,QA版本的名称为<APP-NAME>-QA

我熟悉以下内容:

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

然而,我似乎找不到一个gradle命令来应用在启动器中的应用程序更改。

11个回答

205
如果您所说的“应用程序名称”是指在标签上的android:label属性,最简单的解决方案是将其指向一个字符串资源(例如,android:label="@string/app_name"),然后在src/debug/源集中有不同版本的该字符串资源。
您可以在此示例项目中查看,我在src/debug/res/values/strings.xml中替换了app_name,这将应用于debug构建。release构建将使用src/main/中的app_name版本。

8
@sfera:首先,如果您想要将此字符串单独放置在资源文件中,欢迎这样做。其次,这仅适用于一个字符串。第三,这仅适用于您想要替换该字符串的生成类型。第四,除非您有一个没有共同语言的开发团队,否则您无需翻译非“发布”字符串。 - CommonsWare
1
@sfera:“这就是我试图避免的”--所以,请不要翻译这个字符串。无论如何,测试该字符串将是无效的,因为根据定义,它不是您想在“发布”模式下使用的字符串。并且仅将此字符串资源用于“app_name”,而不用于任何其他角色。 - CommonsWare
3
@sfera:你永远不会发布一个名为“AppNom-DEBUG”的应用程序。你可以发布一个名为“AppNom”的应用程序。因此,测试“AppNom-DEBUG”是不必要的。如果你有法国或德国的开发人员需要翻译调试版本的app_name,你当然可以翻译它,但这并非必要。如果想要测试未修改的release版本的app_name是否能正常工作且翻译正确,可以测试release构建或创建一个“接近发布”的构建类型,只需添加应用程序 ID 后缀,而不改变字符串。 - CommonsWare
当项目中有多个版本时,将strings.xml文件放在/src/debug/res/values/目录下是无效的。相反,您需要在构建类型前指定版本名称,例如:如果您有一个名为Premium的版本,则文件夹名称应为:premiumDebug。@CommonsWare,也许您应该相应地更新您的答案。 - Nimrod Dayan
@CommonsWare 的链接已失效。404错误。 - tenprint
显示剩余5条评论

196

你可以使用类似这样的东西

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

在 AndroidManifest.xml 文件中,您可以使用 @string/app_name

请确保从 values/ 文件夹中删除 app_name(没有该名称的条目)。


当应用程序名称必须从外部文件中读取时,这是完美的。 - Joe Maher
构建时出现错误。任务“:app:mergeDebugResources”执行失败。重复资源:res/values/strings.xml:string/app_name。 - Lalle
7
如果你在构建应用程序时遇到以下错误:Got an error when building this way. Execution failed for task ':app:mergeDebugResources'.. Duplicate resources: res/values/strings.xml:string/app_name,你应该按照如下提示进行操作:"Make sure you remove app_name from values/ folder (no entry by this name)",即确保从values文件夹中移除名为app_name的条目。 - ivan.panasiuk
我喜欢这个解决方案,因为“strings”文件夹的解决方案(上面的已接受的解决方案)仅在为特定源集/产品口味定义应用程序名称时才起作用。在我的情况下,我正在设置一个Jenkins Pipeline作业,以使用不同的名称自动构建我们应用程序的不同版本,并且并非所有这些名称都为它们定义了productFlavors。因此,Jenkins只是通过环境提供应用程序名称,而gradle则读取它:resValue“string”,“app_name”,System.getenv(“APP_NAME”)?:“MyApp” - Aphex
使用多模块设置时,这对我没有起作用。Play控制台一直报告错误的空图标属性,而实际上是我的应用程序名称!我使用了这个链接:https://dev59.com/5mAf5IYBdhLWcg3wUBT4#41301021 - Andre Thiele
显示剩余2条评论

68

你可以使用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


出现错误 - 错误:执行任务“:app:processDevDebugManifest”失败。
清单合并器由于多个错误而失败,请参见日志。
- aj0822ArpitJoshi
无法工作——buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { manifestPlaceholders = [appName: "GridL Debug"] applicationIdSuffix ".dev1" } } - JSONParser
这是唯一对我有效的方法,更糟糕的是Play控制台上的错误报告。它说我的图标是错的,但实际上是我的应用程序名称!这很有帮助!谢谢你! - Andre Thiele

64

为了支持翻译,请执行以下操作:

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>

构建类型有哪些不同种类?除了管理员、发布和调试之外? - Dinesh
@DineshVG 你可以自己设置区别,例如不同的 applicationId。 - NickUnuchek
我想在除了 debug 之外的其他构建配置中使用 UIAutomator 测试,并且使用不同的 pro-guard 规则。这个可行吗? - Dinesh
在多模块设置中,对我不起作用。我使用了这个 https://dev59.com/5mAf5IYBdhLWcg3wUBT4#41301021,它对我有效! - Andre Thiele
我喜欢这个答案,因为它仍然允许我在其他资源中引用生成的字符串,例如 <string name="channel_name">@string/app_name</string> - TomaszRykala
显示剩余2条评论

16

应用程序名称是用户可见的,这就是为什么Google鼓励您将其保留在strings.xml文件中的原因。您可以定义一个单独的字符串资源文件,其中包含特定于您的buildTypes的字符串。听起来您可能有一个自定义的qa buildType。如果不是这样,请忽略下面的qa部分。

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml

1
这个对你有用过吗?我记录了我的例子,但它不起作用... https://dev59.com/goPba4cB1Zd3GeqPv7av - volkersfreunde
这些是口味,而不是构建类型。 - Georgian Benetatos

16
我们需要一个支持应用程序名称本地化的解决方案(适用于多种语言)。 我已经尝试了@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 ]
        }

    }

values\strings.xml:

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

</resources>

values-cn\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>

例如类似于“极品飞车”的游戏,在德国永远不会被称为“Bedürfnis nach Geschwindigkeit(对速度的需求)”,除非它是来自可疑开发者的仿冒产品…… - The incredible Jan
它正在工作。非常感谢。然而,在我的情况下,我需要在AndroidManifest中的application中添加1个更多的tools:replace="android:label" - Linh

6
有多种方法可以做到。
你可以在应用级别的build.gradle中创建manifestPlaceholders 或者 resValue。例如:
buildTypes {
     release {
          ...
          manifestPlaceholders = [appLabel: "My App"]
          //resValue "string", "appLabel", '"My App"'
     }
     debug {
          ...
          manifestPlaceholders = [appLabel: "My App - Debug"]
          //resValue "string", "appLabel", '"My App - Debug"'
     }
}

或者

如果你有productFlavors,你可以在那里创建

flavorDimensions "env"
productFlavors {
    dev {
        dimension "env"
        ...
        manifestPlaceholders = [appLabel: "My App - Development"]
        //resValue "string", "appLabel", '"My App - Development"'
    }
    prod {
        dimension "env"
        ...
        manifestPlaceholders = [appLabel: "My Awesome App"]
        //resValue "string", "appLabel", '"My Awesome App"'
    }
}

然后在 `AndroidManifest.xml` 中,如果您正在使用 `manifestPlaceholders`,只需将 `android:label="${appLabel}"` 更改为以下内容或者如果您正在使用 `resValue`,只需将 `android:label=@string/appLabel` 更改即可。
<application
    ...
    android:label="${appLabel}"> //OR `android:label=@string/appLabel`
    
    <activity
        ...
        android:label="${appLabel}">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

注意:确保在<activity>中也更改android:label,并且必须属于LAUNCHER类别。如果在<activity>中不需要使用android:label,请将其删除。


如果您不想直接添加到build.gradle中,可以在所选的ProductFlavorsvalues/string.xml中添加。例如:

添加

<string name="appLabel">My App - Development</string> 

在`app/src/dev/res/values/string.xml`中

<string name="appLabel">My Awesome App</string> 

app/src/prod/res/values/string.xml 中。

绝对是最佳答案,允许直接从Gradle设置所有应用程序名称变体(如问题所述),而不是搜寻所有单独的res文件夹。如果您可能有来自构建配置的动态应用程序名称,则尤其有用。 - Vin Norman
绝对是最佳答案,可以直接从Gradle设置所有应用程序名称的变体,而不是寻找所有单独的资源文件夹。如果您可能有来自构建配置的动态应用程序名称,这将非常有用。 - undefined

5

如果想要更加灵活的基于gradle的解决方案(例如在主要的strings.xml中设置一个基本应用程序名称,并避免在每个口味/构建类型组合的strings.xml中重复自己),请看我在这里的回答:https://dev59.com/C47da4cB1Zd3GeqP-j4f#32220436


4

您可以在不同的文件夹中使用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 \ 文件夹中。在debug和release文件中替换“Your app name”。从app \ src \ main \ res \ values \ 文件夹中的strings.xml删除app_name 项。
AndroidManifest中你会有相同的内容。
<application
    android:label="@string/app_name"
    ...

没有任何变化。即使您添加了一个带有其AndroidManifest文件和strings.xml的库。


2
作为作者要求在Gradle中进行此操作,我们可以假设他想在脚本中而不是配置文件中执行。由于在过去的一年(~2018),Android StudioGradle都得到了大量更新和修改,因此上面所有其他答案似乎都过于复杂。简单易行的方法是将以下内容添加到您的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"
        }
    }
}

OP正在请求更改应用程序名称,而不是APK名称。 - alizeyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接