У меня есть 2 вкуса, скажем, аромат1 и аромат2 .
Я бы хотел, чтобы мое приложение называлось, скажем, « AppFlavor1 », когда я создаю для варианта 2, и « AppFlavor2 », когда я создаю для варианта 2.
Я хочу изменить не название занятий. Я хочу изменить имя приложения, как оно отображается в меню телефона и в другом месте.
Из build.gradle
я могу установить различные параметры для своих вкусов, но, похоже, не ярлык приложения. И я не могу программно изменить метку приложения на основе какой-то переменной.
Итак, как люди справляются с этим?
sourceSets
блок? Это подandroid{...}
блоком?android
действительно внутри блока.Удалить
app_name
изstrings.xml
(иначе gradle будет жаловаться на повторяющиеся ресурсы). Затем измените файл сборки следующим образом:productFlavors { flavor1{ resValue "string", "app_name", "AppNameFlavor1" } flavor2{ resValue "string", "app_name", "AppNameFlavor2" } }
Также убедитесь, что атрибуту в манифесте
@string/app_name
присвоено значениеandroid:label
.<application ... android:label="@string/app_name" ...
Это менее деструктивно, чем создание новых в
strings.xml
рамках других построенных наборов или написание пользовательских сценариев.источник
@string/app_name
в качествеactivity
ярлыка для лаунчера ? Имейте в виду, что вместо отображаемого имени приложения используетсяlabel
из основного модуля запуска .activity
application
label
Если вы хотите сохранить локализацию имени приложения в разных вариантах, вы можете добиться этого следующим образом:
1) Укажите
android:label
в<application>
наличииAndroidManifest.xml
:<application ... android:label="${appLabel}" ... >
2) Укажите значение по умолчанию fo
appLabel
на уровне приложенияbuild.gradle
:manifestPlaceholders = [appLabel:"@string/defaultName"]
3) Отмените значение аромата продукта следующим образом:
productFlavors { AppFlavor1 { manifestPlaceholders = [appLabel:"@string/flavor1"] } AppFlavor2 { manifestPlaceholders = [appLabel:"@string/flavor2"] } }
4) Добавьте строковые ресурсы для каждой из строк (defaultName, Flavour1, Flavour2) в ваш
strings.xml
. Это позволит вам их локализовать.источник
Вы можете добавить файл ресурсов строки к каждому варианту, а затем использовать эти файлы ресурсов для изменения имени вашего приложения. Например, в одном из моих приложений есть бесплатная и платная версии. Чтобы переименовать их в «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
источник
Другой вариант, который я действительно использую, - это изменение манифеста для каждого приложения. Вместо копирования папки ресурсов вы можете создать манифест для каждого варианта.
sourceSets { main { } release { manifest.srcFile 'src/release/AndroidManifest.xml' } debug { manifest.srcFile 'src/debug/AndroidManifest.xml' } }
У вас должен быть основной AndroidManifest в вашем src main, который будет основным. Затем вы можете определить манифест только с некоторыми параметрами для каждого аромата, например (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>
Компилятор выполнит слияние манифеста, и у вас может быть значок для каждого варианта.
источник
Это легко сделать с помощью 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
источник
Прежде всего, ответьте на вопрос: «Может ли пользователь установить обе разновидности вашего приложения на одном устройстве?»
Я использую скрипт Python, который исправляет исходный код. Он содержит несколько функций многократного использования и, конечно же, информацию о том, что нужно исправить в этом конкретном проекте. Таким образом, сценарий зависит от приложения.
Исправлений много, данные для исправлений хранятся в словаре Python (включая имена пакетов приложений, они, кстати, отличаются от имени пакета 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>
источник
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" >
. После того, как вы очистите и перестроите все (два раза, по одному разу для каждой разновидности), вы должны получить два apk-файла с разными именами пакетов Android и разными метками запуска. Кстати, Eclipse часто не обнаруживает изменений в ресурсах, поэтому вам нужно попросить его очистить.Как мне сделать строку / app_name разными для разных вкусов?
Я хотел написать обновление, но понял, что оно больше, чем исходный ответ, в котором говорится, что я использую скрипт Python, который исправляет источник.
У скрипта Python есть параметр - имя каталога. Этот каталог содержит ресурсы для каждого аромата, ресурсы, такие как значки запуска, и файл properties.txt со словарем Python.
{ '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
источник
В файле AndroidManifest в теге приложения есть такая строка:
android:label
И там вы можете сказать, как метка приложения будет отображаться в меню приложений на устройстве.
источник