Android N - 在运行时更改区域设置

时间:2017-06-14 20:57:59

标签: java android locale android-preferences android-7.0-nougat

我有一个Android应用程序,我想添加一个简单的首选项屏幕,只需一个选项切换到语言(英语和葡萄牙语)。我已经有适当的字符串资源文件。

如果我在系统偏好设置中更改操作系统的主要语言,并重新加载应用程序,它将使用该语言,但我希望能够通过偏好设置屏幕进行操作。

我在其他问题中看到,在以前的Android版本中这样做要容易得多,但是现在不推荐使用该代码,所以我遵循了在每个活动中覆盖attachBaseContext方法的方法,以便通过a重新创建上下文我在首选项中加载当前所选区域设置的包装器,如本文所示:

Android N change language programatically

public class TCPreferenceActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {


@Override
public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.headers_preference, target);
}

@Override
protected boolean isValidFragment(String fragmentName) {
    return TCPreferenceFragment.class.getName().equals(fragmentName);
}


@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals("lang")) {
        recreate();
    }
}



@Override
protected void attachBaseContext(Context newBase) {

    SharedPreferences pref =  PreferenceManager.getDefaultSharedPreferences(newBase);

    String lang = pref.getString("lang", null);

    Locale locale = new Locale(lang);

    Context context = TCContextWrapper.wrap(newBase, locale);
    super.attachBaseContext(context);
}

}

据我所知,在更改首选项时,会调用onSharedPreferenceChanged方法。我重新创建了那里的活动,以便可以使用新的上下文重新启动它。

这是我的上下文包装器:

public class TCContextWrapper extends ContextWrapper {

public TCContextWrapper(Context base) {
    super(base);
}

public static ContextWrapper wrap(Context context, Locale newLocale) {

    Resources res = context.getResources();
    Configuration configuration = res.getConfiguration();

    if (android.os.Build.VERSION.SDK_INT >= 24) {
        configuration.setLocale(newLocale);

        LocaleList localeList = new LocaleList(newLocale);
        LocaleList.setDefault(localeList);
        configuration.setLocales(localeList);

        context = context.createConfigurationContext(configuration);


    } else if (android.os.Build.VERSION.SDK_INT >= 17) {
        configuration.setLocale(newLocale);
        context = context.createConfigurationContext(configuration);

    } else {
        configuration.locale = newLocale;
        res.updateConfiguration(configuration, res.getDisplayMetrics());
    }

    return new ContextWrapper(context);
}

}

调试我可以看到调用了onChange方法,重新创建了首选项活动,调用了上下文包装器,在包装器中正确创建了新的语言环境值,但是当活动启动时,我一直看到相同的默认字符串。 / p>

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您为Language对象设置的

Locale @parameter应为

An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
     * up to 8 characters in length.

根据文件。 因此,如果您正在使用其他内容,则您将看不到更新区域设置。