针对不同构建风格的不同应用名称?

时间:2013-11-07 08:21:34

标签: android gradle

我有2种构建口味,比如说, flavor1 flavor2

当我为flavor2构建时,我希望将我的应用程序命名为“ AppFlavor1 ”,而当我为flavor 2构建时,我希望命名为“ AppFlavor2 ”。

这不是我想要改变的活动的标题。我想更改应用程序名称,因为它显示在手机菜单和其他地方。

build.gradle我可以为我的口味设置各种参数,但似乎不是应用标签。而且我也无法根据某些变量以编程方式更改app标签。

那么,人们如何处理这个问题?

9 个答案:

答案 0 :(得分:201)

从strings.xml中删除app_name(否则gradle会抱怨重复的资源) 然后像这样修改构建文件:

productFlavors {
    flavor1{
        resValue "string", "app_name", "AppFlavor1"
    }

    flavor2{
        resValue "string", "app_name", "AppFlavor2"
    }
   } 

这比在不同的构建集下创建新的strings.xml或编写自定义脚本具有更小的破坏性。

我有一个使用此方法运行的制作应用

https://play.google.com/store/apps/details?id=co.getintouch.play,应用名称为" InTouch Messenger:Premium Edition"

https://play.google.com/store/apps/details?id=co.getintouch,应用名称为" InTouch Messenger"

productFlavors {
    main{
        resValue "string", "app_name", "InTouch Messenger"
    }

    googlePlay{
        resValue "string", "app_name", "InTouch Messenger: GPE Edition"
    }
   } 

别忘了从strings.xml中删除app_name!

答案 1 :(得分:18)

为什么不依赖于Android Gradle构建的标准合并行为,而不是使用脚本更改主strings.xml并且冒着搞乱源代码控制的风险,为什么不依赖于Android Gradle构建的标准合并行为?

我的build.gradle包含

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }

    release {
        res.srcDir 'variants/release/res'
    }

    debug {
        res.srcDir 'variants/debug/res'
    }
}

现在我可以在app_name中定义我的variants/[release|debug]/res/strings.xml字符串。还有其他我想改变的地方!

答案 2 :(得分:8)

您可以为每种风格添加字符串资源文件,然后使用这些资源文件更改您的应用名称。 例如,在我的某个应用中,我有免费和付费版本。重命名他们&#34; Lite&#34;和&#34; Pro&#34;,我创建了一个meta_data.xml文件,并将我的app_name值添加到该XML,并将其从strings.xml中删除。 接下来,在app/src中为每种风格创建一个文件夹(参见下面的示例结构)。在这些目录中,添加res/values/<string resource file name>。现在,在您构建时,此文件将被复制到您的构建中,您的应用程序将被重命名。

文件结构:

app/src
   /pro/res/values/meta_data.xml
   /lite/res/values/meta_data.xml

答案 3 :(得分:5)

我实际使用的另一个选项是更改每个应用程序的清单。您可以为每种风格创建清单,而不是复制资源文件夹。

sourceSets {
  main {
 }

  release {
    manifest.srcFile 'src/release/AndroidManifest.xml'
 }

  debug {
    manifest.srcFile 'src/debug/AndroidManifest.xml'
 }
}

你必须在你的src main中有一个主要的AndroidManifest作为主体。然后你可以定义一个清单,每个选项只有一些选项,如(src / release / AndroidManifest.xml):

<manifest package="com.application.yourapp">
  <application android:icon="@drawable/ic_launcher">
  </application>
</manifest>

对于调试,AndroidManifest(src / debug / AndroidManifest.xml):

<manifest package="com.application.yourapp">
  <application android:icon="@drawable/ic_launcher2">
  </application>
</manifest>

编译器将对清单进行合并,您可以为每种风格添加一个图标。

答案 4 :(得分:5)

如果您想以不同的方式维护应用名称的本地化,那么您可以按如下方式实现:

1)在android:label中的<application>中指定AndroidManifest.xml,如下所示:

<application
    ...
    android:label="${appLabel}"
    ...
>

2)在应用级appLabel中指定默认值fo build.gradle

manifestPlaceholders = [appLabel:"@string/defaultName"]

3)按如下方式覆盖产品口味的值:

productFlavors {
    AppFlavor1 {
        manifestPlaceholders = [appLabel:"@string/flavor1"]
    }
    AppFlavor2 {
        manifestPlaceholders = [appLabel:"@string/flavor2"]
    }

}

4)为strings.xml中的每个字符串(defaultName,flavor1,flavor2)添加字符串资源。这将允许您本地化它们。

答案 5 :(得分:2)

首先,回答这个问题:“用户可以在同一设备上安装两种风格的应用程序吗?”

我使用Python脚本修补源代码。 它包含一些可重用的功能,当然还包括需要在此特定项目中修补的内容。所以脚本是特定于应用程序的。

有很多补丁,补丁的数据保存在Python字典中(包括应用程序包名称,它们BTW与Java包名称不同),每种风格都有一个字典。

对于l10n,字符串可能指向其他字符串,例如在我的代码中我有:

<string name="app_name">@string/x_app_name_xyz</string>

<string name="x_app_name_default">My Application</string>
<string name="x_app_name_xyz">My App</string>

答案 6 :(得分:1)

这可以在buildTypes

下轻松完成
buildTypes {
    debug {
        buildConfigField("String", "server_type", "\"TEST\"")
        resValue "string", "app_name", "Eventful-Test"
        debuggable true
        signingConfig signingConfigs.debug_key_sign
    }

    stage {
        buildConfigField("String", "server_type", "\"STAGE\"")
        resValue "string", "app_name", "Eventful-Stage"
        debuggable true
        signingConfig signingConfigs.debug_key_sign
    }

    release {
        buildConfigField("String", "server_type", "\"PROD\"")
        resValue "string", "app_name", "Eventful"
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        //TODO - add release signing
    }
}

只需确保从strings.xml中删除app_name

答案 7 :(得分:0)

如何使每个风格的字符串/ app_name不同?

我想写一个更新,但意识到它比原来的答案更大,说我使用的是修补源代码的Python脚本。

Python脚本有一个参数,一个目录名。该目录包含每个风味资产,启动器图标等资源以及带有Python字典的文件properties.txt。

{ 'someBoolean' : True
, 'someParam' : 'none'
, 'appTitle' : '@string/x_app_name_xyz'
}

Python脚本从该文件加载字典,并将<string name="app_name"></string>之间的值替换为properties['appTitle']的值。

以下代码按原样/原样提供等。

for strings_xml in glob.glob("res/values*/strings.xml"):
    fileReplace(strings_xml,'<string name="app_name">',properties['appTitle'],'</string>',oldtextpattern=r"[a-zA-Z0-9_/@\- ]+")

从一个或多个此类文件中读取属性:

with open(filename1) as f:
    properties = eval(f.read())
with open(filename2) as f:
    properties.update(eval(f.read()))

并且fileReplace函数是:

really = True
#False for debugging

# In the file 'fname',
# find the text matching "before oldtext after" (all occurrences) and
# replace 'oldtext' with 'newtext' (all occurrences).
# If 'mandatory' is true, raise an exception if no replacements were made.
def fileReplace(fname,before,newtext,after,oldtextpattern=r"[\w.]+",mandatory=True):
    with open(fname, 'r+') as f:
        read_data = f.read()
        pattern = r"("+re.escape(before)+r")"+oldtextpattern+"("+re.escape(after)+r")"
        replacement = r"\g<1>"+newtext+r"\g<2>"
        new_data,replacements_made = re.subn(pattern,replacement,read_data,flags=re.MULTILINE)
        if replacements_made and really:
            f.seek(0)
            f.truncate()
            f.write(new_data)
            if verbose:
                print "patching ",fname," (",replacements_made," occurrence" + ("s" if 1!=replacements_made else ""),")",newtext,("-- no changes" if new_data==read_data else "-- ***CHANGED***")
        elif replacements_made:
            print fname,":"
            print new_data
        elif mandatory:
            raise Exception("cannot patch the file: "+fname+" with ["+newtext+"] instead of '"+before+"{"+oldtextpattern+"}"+after+"'")

脚本的第一行是:

#!/usr/bin/python
# coding: utf-8

import sys
import os
import re
import os.path
import shutil
import argparse
import string
import glob
from myutils import copytreeover

答案 8 :(得分:-3)

在AndroidManifest文件中,在应用程序标记中有这一行:

android:label

在那里你可以说如何在设备的应用程序菜单中显示应用程序标签