【问题标题】:Changing locale programmatically not working in some devices以编程方式更改语言环境在某些设备中不起作用
【发布时间】:2014-04-17 11:07:50
【问题描述】:

我有以下代码:

/**
 * Sets a new Locale for the APP.
 * @param newLocale - Valid new locale.
 */
private static void setLocale( String newLocale )
{
    Locale locale = new Locale( newLocale );
    Locale.setDefault( locale );

    Configuration config = new Configuration();
    config.locale = locale;

    context.getResources().updateConfiguration( config, context.getResources().getDisplayMetrics() );
}

简单。

但是,当我在智能手机 (4.1.1) 中运行它时,它确实可以完美运行。设备会更改字符串以匹配语言。

但是对于平板电脑 (4.3),它不起作用。如果我输出类似:

Log.d("TAG",Locale.getDefault());

两个设备上的区域设置似乎都已更改,但正如我所说,字符串没有被翻译成正确的语言。

我做了很多调试,发现了对象之间的区别: 查看 4.1.1 上的配置对象:

并查看平板电脑上的配置对象 (4.3)

如您所见,唯一显着的区别是userSetLocale 在平板电脑上设置为 False。

所以我检查了 Google 源代码 (https://github.com/android/platform_frameworks_base/blob/master/core/java/android/content/res/Configuration.java),它指出:

 /**
 * Locale should persist on setting.  This is hidden because it is really
 * questionable whether this is the right way to expose the functionality.
 * @hide
 */
public boolean userSetLocale;

看来这对我有影响。因此,由于我无法访问此值,也无法通过 getter / setter 或公共访问,我使用反射来更改它。

但是,在通过反射更改它之后,即使我已经看到它在内部发生了变化(反射后布尔值设置为 false),同样的问题仍然存在。

你们有什么建议吗?

同时我会继续测试。

谢谢。 测试:

  • Nexus 10 - 4.4.2 - 正常
  • Nexus 5 - 4.4.2 - 正常
  • 平板电脑 320 dpi - 4.4.2 - 正常
  • 智能手机 480 dpi - 4.3 - 正常
  • 智能手机 160 dpi - 4.1.1 - 正常
  • 平板电脑 160 dpi - 4.3 - 不行
  • 智能手机 320 dpi - 4.1.1 - 正常

【问题讨论】:

  • 好的。我完成了测试。我使用 Genymotion 模拟器和两个真实设备做到了这一点。如您所见,出现问题的似乎是 160dpi 和 4.3 的平板电脑。 IDK 如果这是该版本的错误。我会尝试继续测试设备。
  • 当不是所有语言都包含在编译中时,这是一个问题。这就是为什么过去有像locale 这样的应用程序来解决这个问题的原因。将设置语言环境,但大部分文本将不翻译。这个问题没有通用的解决方案,只有变通方法。您唯一能做的就是自己为该设备编译 Android 并附加适当的语言。您可以在 Android 设置菜单中查看已安装和可用的语言。
  • 什么?我想我解释得不够好。对于每种语言,我都有几个文件夹。 values-pl, values-zh, values-es, values-en 等等设备,它被忽略了。
  • 也许我不明白这个问题的复杂性。但你的意思是在你的应用范围内?如果您拥有所有可用的翻译(就像您说的那样),那么一切都应该改变。在系统级别上,自定义语言环境可能存在问题。
  • 是的。翻译还可以,因为其他设备可以完美地使用它们。这就是奇怪的事情。我用Locale.getAvailableLocales() 检查了可用的语言环境,并且有几个语言环境与我的新语言环境相匹配,例如es_ES。下周我将尝试弄清楚这是否仅发生在单个设备(即 Genymotion 模拟器)中,或者它是否也确实发生在真实设备上。同时,如果您有一些想法,我们非常欢迎他们 =)

标签: java android


【解决方案1】:

这是我用于本地化的代码。它被超过 100 万人使用,从未听说过任何关于不更改字符串的抱怨,所以我希望它也对你有用:

一流的:

Locale myLocale;

功能:

    public void setLocale(String lang) { 
        myLocale = new Locale(lang); 
        Resources res = getResources(); 
        DisplayMetrics dm = res.getDisplayMetrics(); 
        Configuration conf = res.getConfiguration(); 
        conf.locale = myLocale; 
        res.updateConfiguration(conf, dm);
        reloadUI(); // you may not need this, in my activity ui must be refreshed immediately so it has a function like this.
    }

函数调用:

//example for setting English
setLocale("en_gb");

【讨论】:

  • 方法在某种程度上完全相同:) 创建全新配置或更新当前配置之间没有区别。正如我所说,这个问题只发生在单个设备中。我猜那个ROM根本不正确
  • 是的,我知道它们看起来很相似,但并不“完全”相同。您创建新配置,我从资源中获取。试试这个功能不会有什么坏处,试一试很容易^^就像我说的,对于我的项目,我没有收到任何关于 Locale 的抱怨。想和你分享
  • 你好。我刚试过。同样的情况,我已经尝试过了,从创建一个新的语言环境,到获取当前的语言环境并改变它。配置相同。检查不想正常工作的模拟器:i.imgur.com/TQtm5iq.png也许你可以在这个设备上试试你的APP(它是一个Genymotion模拟器)
  • 创建新配置和更新当前配置是不一样的。如果您创建一个新值,您将失去旧值。例如。大文本可访问性设置将不会应用于您的应用(菜单和设置字体大小不会反映对有视力问题的用户有用的设置)。
【解决方案2】:

嗯,

用户 Sir SC 提供了一个有效的答案。但是我的代码也有效。我们面临的问题是关于忽略此语言环境更改的单个设备。所以 AFAIK,它只是一个单独的设备,它可能是由于一个有问题的 ROM 造成的,因为它是一个 Genymotion 模拟器。

总的来说,答案是:

  • 发布的代码 OP 有效且有效。 SC 爵士的代码也是如此。

干杯。

【讨论】:

  • 这不是你回答的方式。如果有人发布了有效代码,请将其标记为答案并在其下方写下您的 cmets。
猜你喜欢
  • 1970-01-01
  • 2019-03-28
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多