Подтвердить что ты не робот

Различные имена приложений для разных вариантов сборки?

У меня есть 2 аромата сборки, скажем, flavor1 и flavor2.

Я хочу, чтобы мое приложение было названо, скажем, "AppFlavor1", когда я создаю для flavor1 и "AppFlavor2", когда создаю для аромата 2.

Это не название деятельности, которую я хочу изменить. Я хочу изменить имя приложения, которое отображается в меню телефона и в другом месте.

От build.gradle Я могу установить различные параметры для своих вкусов, но, похоже, не для метки приложения. И я также не могу изменить метку приложения программно на основе некоторой переменной.

Итак, как люди справляются с этим?

4b9b3361

Ответ 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

И там вы можете сказать, как метка приложения появится в меню приложений на устройстве