不同的应用程序名称为不同的构build口味?

我有2种口味,比如flavor1flavor2

我希望我的应用程序被命名为“ AppFlavor1 ”,当我为flavor1构build时,“ AppFlavor2 ”在我构buildflavor2时被命名。

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

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

那么,人们如何处理呢?

为什么不依靠Android Gradle构build的标准合并行为,而不是使用脚本来更改主要的strings.xml,

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

所以现在我可以在variants/[release|debug]/res/strings.xml定义我的app_namestring。 还有我想改变的东西!

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

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

这比在不同的构build集合下创build新的strings.xml或编写自定义脚本的操作更less。

我有一个生产应用程序运行使用这种方法

https://play.google.com/store/apps/details?id=co.getintouch.play与应用程序名称“InTouch Messenger:高级版”

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

不要忘记从st​​rings.xml中删除app_name!

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

文件结构:

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

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

我使用一个Python脚本来修补源代码。 它包含一些可重用的function,当然还有知道在这个特定项目中需要修补的东西。 所以这个脚本是特定于应用程序的。

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

至于l10n,string可能指向其他string,例如在我的代码中我有:

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

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

 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> 

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

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

编译器会做清单的合并,你可以为每个风格有一个图标。

我如何使string/ app_name不同每味道?

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

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

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

Python脚本从该文件加载字典,并使用properties['appTitle']的值replace<string name="app_name"></string>的值。

以下代码是按原样提供的。

 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 

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

 android:label 

在那里你可以说如何应用程序标签将出现在设备上的应用程序菜单