android - 使用 resConfig 为 Android 风格强制语言环境

标签 android gradle localization locale android-productflavors

我正在尝试使用 Android 构建系统中的 resConfig 和 resConfigs。

  • Android Studio 版本 1.2.2
  • Gradle 构建版本 1.2.3
  • 操作系统 10.10.3

我在我的项目中遇到了这两个选项的问题,所以我用 android studio 开始了一个新的空白项目。我附上了我的 build.gradle,我只在

下添加了 resConfigs "en", "fr"
android { 
   defaultConfig {
        ...
        resConfigs "en", "fr" 
        ...
   }
}

并定义了2种基本口味

productFlavors {
        fr {
            resConfig "fr"
        }

        en {
            resConfig "en"
        }
}

然后我创建了 2 个 strings.xml 文件并翻译了 hello_world 默认标签

/src/main/res/values/strings.xml (default)
/src/main/res/values-en/strings.xml
/src/main/res/values-fr/strings.xml

有了这个,我希望在 MyApplication/app/builds/intermediates/res/en/debug 中只看到 3 个值文件夹,因为我在 resConfigs 中定义为仅使用“en”和“fr”并过滤任何其他内容

/values/
/values-en/
/values-fr/

尽管如此,所有语言值文件夹仍在那里,因此 resConfigs 显然没有过滤任何内容。

我还希望在运行 enDebug flavor 变体时看到来自 values-en 的标签 hello_world,因为我指定 flavor en 将使用 resConfig“en”,尽管当我运行测试应用程序时我看到来自/values-fr 的标签/strings.xml 而不是/values-en/strings.xml,因为平板电脑上的语言配置为加拿大法语

我是否误解了 resConfig 背后的目的?如果是这样,我应该如何强制一种风格只以语言运行而不依赖于操作系统区域设置?此解决方案也必须与 flavorDimensions 兼容,因为我在我尝试配置的真实应用程序中使用它们。

注意:我还提交了一个错误,因为我认为这个 resConfig 行为确实存在问题 https://code.google.com/p/android/issues/detail?id=180694

谢谢

最佳答案

好吧,几个小时后,对于那些最终遇到同样问题的人,这是我的问题的解决方案。

原来 resConfig 不是我想的那样。我发现为特定 flavor 强制使用语言环境的正确且唯一的方法是这样的:

首先,确保您的所有 Activity 都扩展了一个共同的 Activity ,该 Activity 将负责强制执行语言环境。 (我必须创建 2,因为我有一些扩展 FragmentActivity 的 Activity 和一些扩展 Activity。我也不太喜欢在 Activities 构造函数中这样做,但是因为我必须在对 getResources 进行任何调用之前调用 applyOverrideConfiguration,我需要在 Activity 的 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);      
}

接下来,您需要在 build.gradle flavors 中定义语言环境

productFlavors {

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

我在 API 19+ 上测试了该解决方案。当您在应用程序中更改语言时也适用。



替代解决方案(不适用于 Android M+ see android bug report ) 这个解决方案在 stackOverflow 上广泛传播,但我在 Android M 上实现它时遇到了困难,所以请记住这一点。

在您的 AndroidApplication 的 onCreate() 中,您可以使用区域设置调用 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());
    }

编辑:请注意,此 applyOverrideConfiguration 目前有一个副作用,在此处解释 Chromium webview does not seems to work with Android applyOverrideConfiguration . Chromium 团队目前正在努力解决这个问题!

谢谢。

关于android - 使用 resConfig 为 Android 风格强制语言环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31566270/

相关文章:

java - 如何使用 BiometricManager 或 BiometricPrompt 检查生物识别硬件是否可用?

android - 首次启动应用程序时 WebView 无法登录

android - 如何构建可拉伸(stretch)的复杂 View ?

java - 在 Intellij IDEA 中外部化时如何自动编码 Unicode 字符串

php - 区域化内容显示给具有配置文件中匹配区域的用户

android - getActivity() 在我的 ActivityInstrumentationTestCase2 类中返回 null

android - 为什么我不能添加我的项目依赖项?

gradle - 如何覆盖 build.gradle 中定义的属性?

xml - 如何使用 Groovy/idea 插件来操作 intelliJ IDEA XML?

具有非默认语言环境的 ActionBar NullPointerException 的 Android 应用程序