首页 文章

Android获取设备区域设置

提问于
浏览
35

安装我的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()是否提供当前应用的区域设置?
如何获取设备的区域设置?

编辑:在应用程序的首次运行中,它是一个保存设备区域设置的选项 . 但是如果用户在保存后更改设备区域设置,则无法知道设备的新区域设置 . 我只能知道我在app install中保存的语言环境 .

7 回答

  • 3

    除了使用反射或解析某些系统属性之外,还有一种更简单,更简洁的方法 .

    正如您在应用程序中设置默认区域设置时所注意到的那样,您无法再访问系统默认区域设置 . 您在应用中设置的默认区域设置仅在应用的生命周期内有效 . 一旦进程终止,您在Locale.setDefault(Locale)中设置的内容就会消失 . 重新启动应用程序后,您将再次能够读取系统默认的区域设置 .

    所以你需要做的就是在应用程序启动时检索系统默认的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将为您提供答案 .

    我在你的代码中发现了一个问题 . 设置新的区域设置时,您执行以下操作:

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

    执行此操作时,将覆盖您可能要保留的所有配置信息 . 例如 . Configuration.fontScale反映了Access Text设置Large Text . 通过设置语言并丢失所有其他配置,您的应用程序将不再反映大文本设置,这意味着文本比应该更小(如果用户启用了大文本设置) . 正确的方法是:

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

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

  • 1

    您可以访问全局区域设置 -

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

    看看http://developer.android.com/reference/android/content/res/Resources.html#getSystem() -

    返回一个全局共享的Resources对象,该对象仅提供对系统资源的访问(无应用程序资源)

    更新:正如评论中指出'locale'字段已弃用,您需要使用getLocales() .

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

  • 1

    设计应用程序的最佳方法是使用默认的lang,在您的情况下使用英语,在值/下,您可以在值-XX /下添加额外的lang . 这种方式当一种语言不支持Android回退到你的默认,所以英语 . 让操作系统为您完成工作:)但是,是的,如果您更改区域设置,您将获得最后的设置,因此您必须在某处保存该信息 .

  • 7

    As you are changing the 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.
    

    So instead of that use this below code to get the 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();
    }
    

    OUTPUT: Spanish Check this

    希望这正是你要找的 .

  • 40

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

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

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

  • 67

    虽然@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(Estados Unidos)后跟字符串

    <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)));
    }
    

    得出以下屏幕:

    System locale screenshot

    如果需要,还可以使用上面的内容轻松构造 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
    

    希望这个帮助 .

  • -1

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

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

    current.toString() 将返回"en" "ar"等

相关问题