Android获取设备区域设置

2wnc66cl  于 2022-12-09  发布在  Android
关注(0)|答案(7)|浏览(307)

在安装我的Android程序时,我检查设备区域设置:

String deviceLocale=Locale.getDefault().getLanguage();

如果deviceLocale在我支持的语言范围内(英语、法语、德语),我不会更改区域设置。
但例如,如果我不支持设备的语言:例如西班牙语。
我将当前区域设置为英语,因为大多数人都能部分理解英语。

Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

但在这之后,在其他方法中,当我检查设备的区域设置时,如下所示:

String deviceLocale=Locale.getDefault().getLanguage();

我得到的结果是“英语”。但设备的区域设置是西班牙语。
getLanguage()是否提供当前应用的区域设置?
如何获取设备的区域设置?
编辑:在应用程序的第一次运行,它是一个选项,以保存设备区域设置。但如果用户改变设备区域设置后,我保存,我不能知道新的设备区域设置。我只能知道我保存在应用程序安装的区域设置。

lc8prwob

lc8prwob1#

与使用反射或解析某些系统属性相比,有一种更简单、更干净的方法来实现这一点。
正如您所注意到的,一旦您在应用程序中设置了默认区域设置,您就无法再访问系统默认区域设置。您在应用程序中设置的默认区域设置仅在应用程序的生命周期内有效。一旦进程终止,您在Locale.setDefault(Locale)中设置的任何内容都会消失。当应用程序重新启动时,您将再次能够读取系统默认区域设置。
因此,您只需在应用启动时检索系统默认的区域设置,在应用运行期间记住该区域设置,并在用户决定更改Android设置中的语言时更新该区域设置。由于我们仅在应用运行期间需要该信息,因此我们只需将其存储在一个静态变量中,即可从应用中的任何位置访问该变量。
我们的做法是:

public class MyApplication extends Application {
    
    public static String sDefSystemLanguage;
    
    @Override
    public void onCreate() {
        super.onCreate();

        sDefSystemLanguage = Locale.getDefault().getLanguage();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        sDefSystemLanguage = newConfig.locale.getLanguage();
    }

}

使用应用程序(不要忘记在清单中定义它),我们会在应用程序启动时(onCreate())获取默认区域设置,并在用户更改Android设置中的语言时(onConfigurationChanged(Configuration))更新该区域设置。仅此而已。每当您需要在使用setDefault调用之前了解系统默认语言时,sDefSystemLanguage都会为您提供答案。
我在你的代码中发现了一个问题。当你设置新的Locale时,你需要:

Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

当您这样做时,您会覆盖您可能想要保留的所有配置信息。例如,配置.fontScale反映了辅助功能设置大文本。通过设置语言并丢失所有其他配置,您的应用将不再反映大文本设置,这意味着文本比它应该的大小要小(如果用户启用了大文本设置)。正确的方法是:

Resources res = pContext.getResources();
Configuration config = res.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    configuration.setLocale(locale);
}
else {
    configuration.locale = locale;
}
res.updateConfiguration(config, null);

因此,我们只需更新当前的Configuration对象,而不是创建新的Configuration对象。

umuewwlo

umuewwlo2#

更新:正如在评论中指出的,“语言环境”字段已过时,您需要使用getLocales()来代替。

defaultLocale = Resources.getSystem().getConfiguration().getLocales().get(0);

您可以通过以下方式访问全局区域设置-

defaultLocale = Resources.getSystem().getConfiguration().locale;

请访问:http://developer.android.com/reference/android/content/res/Resources.html#getSystem()-
返回一个全局共享资源对象,该对象仅提供对系统资源(无应用程序资源)的访问

ccrfmcuu

ccrfmcuu3#

设计应用程序的最佳方式是在values/下使用默认语言(英语),您可以在values-XX/下添加附加语言。这样,当不支持某个语言时,Android会返回到默认语言(英语)。让操作系统为您完成工作:)但是,如果您更改了区域设置,您将获得最后的设置,因此您必须将该信息保存在某个地方。

k4aesqcs

k4aesqcs4#

当您变更Application language programatically like

Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

还有

But after that, in other methods, when I check device's locale like this:

String deviceLocale=Locale.getDefault().getLanguage();
I get result as "English". But device's locale is Spanish.

因此,请使用以下代码获取device's Local

try {
    Process exec = Runtime.getRuntime().exec(new String[]{"getprop", "persist.sys.language"});
    String locale = new BufferedReader(new InputStreamReader(exec.getInputStream())).readLine();
    exec.destroy();
    Log.e("", "Device locale: "+locale);
} catch (IOException e) {
    e.printStackTrace();
}

输出:SpanishCheck this

希望这正是你要找的。

hm2xizp9

hm2xizp95#

您应该使用String deviceLocale= Locale.getDefault().getDisplayLanguage();来显示语言,而不是

String deviceLocale=Locale.getDefault().getLanguage();

看看这个答案,它可能会帮助你,如果上面没有.

hc2pp10m

hc2pp10m6#

虽然@user2944616的回答在政治上是正确的,但这并不能回答实际提出的问题。
因此,如果我真的必须知道用户设置的系统区域设置,我会使用反射(不知道还有什么更好的选项ATM):

private String getSystemPropertyValue(String name) {
    try {
        Class<?> systemProperties = Class.forName("android.os.SystemProperties");
        try {
            Method get = systemProperties.getMethod("get", String.class, String.class);
            if (get == null) {
                return "Failure!?";
            }
            try {
                return (String)get.invoke(systemProperties, name, "");
            } catch (IllegalAccessException e) {
                return "IllegalAccessException";
            } catch (IllegalArgumentException e) {
                return "IllegalArgumentException";
            } catch (InvocationTargetException e) {
                return "InvocationTargetException";
            }
        } catch (NoSuchMethodException e) {
            return "SystemProperties.get(String key, String def) method is not found";
        }
    } catch (ClassNotFoundException e) {
        return "SystemProperties class is not found";
    }
}

在给定的情况下,设备区域设置为西班牙语(美国)/ Español(美国),以下字符串

<string name="system_locale">System locale: <xliff:g id="profile_name">%1$s</xliff:g>&#95;<xliff:g id="device_name">%2$s</xliff:g></string>

并且该代码

private static final String SYS_COUNTRY = "persist.sys.country";
private static final String SYS_LANG = "persist.sys.language";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView tv = (TextView)findViewById(R.id.locale);
    tv.setText(getString(R.string.system_locale, getSystemPropertyValue(SYS_LANG),
            getSystemPropertyValue(SYS_COUNTRY)));
}

生成以下屏幕:

如果需要,还可以使用上面的代码轻松构建Locale示例:

Locale locale = new Locale(getSystemPropertyValue(SYS_LANG),
        getSystemPropertyValue(SYS_COUNTRY));
Log.d(TAG, "Language: " + locale.getLanguage());
Log.d(TAG, "Country: " + locale.getCountry());

日志输出:

D/GetSystemLocale(5697): Language: es
D/GetSystemLocale(5697): Country: US

希望这对你有帮助。

khbbv19g

khbbv19g7#

要获取设备区域设置,请使用此

Locale current = context.getResources().getConfiguration().locale;

current.toString()将返回“en”“ar”等

相关问题