Различные имена приложений для разных вариантов сборки?
У меня есть 2 аромата сборки, скажем, flavor1 и flavor2.
Я хочу, чтобы мое приложение было названо, скажем, "AppFlavor1", когда я создаю для flavor1 и "AppFlavor2", когда создаю для аромата 2.
Это не название деятельности, которую я хочу изменить. Я хочу изменить имя приложения, которое отображается в меню телефона и в другом месте.
От build.gradle
Я могу установить различные параметры для своих вкусов, но, похоже, не для метки приложения. И я также не могу изменить метку приложения программно на основе некоторой переменной.
Итак, как люди справляются с этим?
Ответы
Ответ 1
Вместо того, чтобы менять основной файл strings.xml с помощью script и рисковать запуском вашего исходного элемента управления, почему бы не полагаться на стандартное слияние поведения Android Gradle build?
My 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
Удалить имя_пользователя из strings.xml(else 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"
}
}
Не забудьте удалить app_name из strings.xml!
Ответ 3
Вы можете добавить файл ресурсов строк для каждого аромата, а затем использовать эти файлы ресурсов для изменения имени вашего приложения.
Например, в одном из моих приложений у меня есть бесплатная и платная версия. Чтобы переименовать их "Lite" и "Pro", я создал файл 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
Ответ 4
Другим вариантом, который я фактически использую, является изменение манифеста для каждого приложения. Вместо копирования папки ресурсов вы можете создать манифест для каждого аромата.
sourceSets {
main {
}
release {
manifest.srcFile 'src/release/AndroidManifest.xml'
}
debug {
manifest.srcFile 'src/debug/AndroidManifest.xml'
}
}
У вас должен быть основной AndroidManifest в главной директории src, который будет основным. Затем вы можете определить манифест только с некоторыми параметрами для каждого такого вкуса (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>
Компилятор выполнит слияние манифеста, и у вас может быть значок для каждого аромата.
Ответ 5
Если вы хотите поддерживать локализацию имени приложения в разных вариантах, вы можете достичь его следующим образом:
1) Укажите android:label
в <application>
доступный в AndroidManifest.xml
следующим образом:
<application
...
android:label="${appLabel}"
...
>
2) Укажите значение по умолчанию для appLabel
в уровне приложения build.gradle
:
manifestPlaceholders = [appLabel:"@string/defaultName"]
3) Отмените значение для ароматов продукта следующим образом:
productFlavors {
AppFlavor1 {
manifestPlaceholders = [appLabel:"@string/flavor1"]
}
AppFlavor2 {
manifestPlaceholders = [appLabel:"@string/flavor2"]
}
}
4) Добавить строку ресурсов для каждого из струнных (defaultName, flavor1, flavor2) в вашем strings.xml
. Это позволит вам локализовать их.
Ответ 6
Прежде всего, ответьте на этот вопрос: "Может ли пользователь установить оба варианта вашего приложения на одном устройстве?"
Я использую Python script, который исправляет исходный код.
Он содержит некоторые функции многократного использования и, конечно же, знания, которые должны быть исправлены в этом конкретном проекте. Таким образом, script зависит от приложения.
Существует много исправлений, данные для исправления хранятся в словаре 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>
Ответ 7
Как я могу сделать string/app_name разными для каждого вкуса?
Я хотел написать обновление, но понял, что он больше, чем оригинальный ответ, говорящий, что я использую Python script, который исправляет исходный код.
У Python script есть параметр, имя каталога. Этот каталог содержит атрибуты для каждого вкуса, такие ресурсы, как значки запуска, и файл properties.txt с помощью словаря Python.
{ 'someBoolean' : True
, 'someParam' : 'none'
, 'appTitle' : '@string/x_app_name_xyz'
}
Python script загружает словарь из этого файла и заменяет значение между <string name="app_name">
и </string>
значением properties['appTitle']
.
Ниже приведен код на основе as-is/as-was и т.д.
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+"'")
Первые строки script:
#!/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
Это можно легко выполнить в 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
}
}
Просто удалите app_name из strings.xml
Ответ 9
В файле AndroidManifest в теге приложения у вас есть эта строка:
android:label
И там вы можете сказать, как метка приложения появится в меню приложений на устройстве