Локаль силы для вкуса андроида с resConfig

Я пытаюсь использовать resConfig и resConfigs из системы сборки Android.

  • Android Studio версии 1.2.2
  • Gradle build версии 1.2.3
  • OSX 10.10.3

у меня возникли проблемы с этими 2 вариантами с моим проектом, поэтому я начал новый пустой проект с Android studio. Я прикрепил свою сборку.gradle, где я только добавил resConfigs "en", " fr " под

android { 
   defaultConfig {
        ...
        resConfigs "en", "fr" 
        ...
   }
}

и определено 2 основных ароматы

productFlavors {
        fr {
            resConfig "fr"
        }

        en {
            resConfig "en"
        }
}

Я создал 2 строки.xml-файлы и переведена метка hello_world по умолчанию

/ src / main/res/values / strings.xml (по умолчанию)
/ src / main/res/values-en / strings.в XML
/ src / main/res/values-FR / strings.в XML

С этим я ожидал бы увидеть только 3 папки значений в MyApplication / app/builds/intermediates/res/en / debug, так как я определил в resConfigs использовать только " en " и " fr " и фильтровать все остальное

/ values/
/значения-Ан/
/ значения-fr/

хотя папка значений всех языков все еще находится там, поэтому resConfigs ничего не фильтрует.

Я также ожидал бы увидеть метку hello_world из values-en при запуске варианта вкуса enDebug, так как я указал, что flavor en будет использовать resConfig "en", хотя при запуске тестового приложения я вижу метку из / values-FR / strings.xml вместо /values-en / strings.xml так как язык на планшете настроен как French Canada

Я неправильно понимаю цель resConfig? Если да, то как я должен заставить аромат работать только на одном языке и не зависеть от настроек локали ОС? Это решение должно быть совместимо с flavorDimensions, так как я использую их в реальном приложении, которое я пытаюсь настроить.

Примечание: я также подал ошибку, так как я думаю, что действительно есть проблема с этим поведением resConfighttps://code.google.com/p/android/issues/detail?id=180694

спасибо

2 ответов


Ну, после многих часов, вот решение моей проблемы для тех, кто в конечном итоге с той же проблемой.

оказывается, resConfig не для того, что я, хотя. Правильный и единственный способ, который я нашел, чтобы заставить локаль для определенного вкуса, таков:

во-первых, убедитесь, что все ваши действия расширяют общую деятельность, которая будет отвечать за принудительную локаль. (мне пришлось создать 2, так как у меня есть некоторые действия, расширяющие FragmentActivity и некоторые расширения Деятельность. Мне также не очень нравится делать это в конструкторе действий, но так как я должен вызвать applyOverrideConfiguration перед любым вызовом getResources, мне нужно вызвать его перед onStart действия).

public class LocaleMainActivity extends Activity {

    public LocaleMainActivity() {
        ActivityUtils.forceLocale(this);
    }
}

public class LocaleMainFragmentActivity extends FragmentActivity {

    public LocaleMainFragmentActivity() {
        ActivityUtils.forceLocale(this);
    }
}

//Method from ActivityUtils
public static void forceLocale(ContextThemeWrapper contextThemeWrapper) {
    Configuration configuration = new Configuration();
    Locale defaultLocale = new Locale(BuildConfig.LOCALE);
    configuration.locale = defaultLocale;
    contextThemeWrapper.applyOverrideConfiguration(configuration);      
}

затем вам нужно определить локаль в вашей сборке.Gradle в ароматизаторы

productFlavors {

    myFrenchFlavor {
     buildConfigField "String", "LOCALE", "\"fr\""
    }
    myEnglishFlavor {
      buildConfigField "String", "LOCALE", "\"en\""
    }
}

я протестировал решение на API 19+. Работает, когда вы меняете язык, находясь в приложении.



альтернативный решение (не будет работать на Android M+ см. отчет об ошибке android) Это решение широко распространено на stackOverflow, но я столкнулся со стеной при реализации этого на Android M, поэтому имейте это в виду.

в onCreate () вашего AndroidApplication вы можете вызвать updateConfiguration с набором языковых стандартов.

Locale myLocale = new Locale(BuildConfig.LOCALE);
Resources res = getResources();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, res.getDisplayMetrics());

вам также нужно будет сбросить его, если вы определили onConfigurationChanged ()

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);            
        Configuration config = new Configuration(newConfig);
        config.locale = new Locale(BuildConfig.LOCALE);
        getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
    }

EDIT: будет известно, что это applyOverrideConfiguration в настоящее время имеет побочный эффект, который объясняется здесь Chromium webview, похоже, не работает с Android applyOverrideConfiguration. Команда Chromium в настоящее время работает над этим!

спасибо.


resConfig не отменяет указанного resConfigs на defaultConfig, но объединяет их вместо. Таким образом, вы получите все ароматы, содержащие en и fr ресурсы.

чтобы избежать этого, вы не должны указывать какие-либо resConfigs на defaultConfig и просто установите его в определенном вкусе.

кроме того, приложение всегда будет включать по умолчанию values, что означает, если у вас есть английские строки,fr вкус по-прежнему будет отображаться с английским контентом на устройстве, установленном в любом не французском языке.