Android 6上的Android语言没有改变

Android 6上的Android语言没有改变,android,locale,Android,Locale,我正在尝试更改应用程序中的语言。当用户单击按钮时,我将语言保存到SharedReferences,并调用super.recreate() 那么我有这个代码: protected void attachBaseContext(Context newBase) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(newBase); lng = prefs.getString("

我正在尝试更改应用程序中的语言。当用户单击按钮时,我将语言保存到SharedReferences,并调用
super.recreate()

那么我有这个代码:

protected void attachBaseContext(Context newBase) {

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(newBase);
    lng = prefs.getString("mylang", "sk");

    Locale locale = new Locale(lng);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Configuration config = new Configuration(newBase.getResources().getConfiguration());
        Locale.setDefault(locale);config.setLocale(locale);
        newBase = newBase.createConfigurationContext(config);

    }  else {Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        newBase.getResources().updateConfiguration(config,
        newBase.getResources().getDisplayMetrics());
    }

    super.attachBaseContext(newBase);
}
这在设备>=Android N上运行得非常好,但在较低版本上,语言没有改变

所以问题就在这一部分:

 else {Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    newBase.getResources().updateConfiguration(config,
                             newBase.getResources().getDisplayMetrics());
}
我试图将
newBase
替换为
this
getApplicationContext()
,但出现了空指针异常。但如果我离开那里,语言不会改变

奇怪的是,如果我删除整个
attachBaseContext
方法,并将旧设备的代码放在onclick方法中:

 this.getResources().updateConfiguration(config,
                            this.getResources().getDisplayMetrics());
这样,它可以在旧设备上工作。但我需要attachBaseContext,因为较新版本不受欢迎。但是如果我把
attachBaseContext
放回原处,那么它就不起作用了,所以我想,对于旧的机器人,
attachBaseContext
里面有些错误

更新:

如果我删除
attachBaseContext
并将代码放到
onCreate
,则该语言适用于旧设备,但不适用于新的Android:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Configuration config = new Configuration(getBaseContext().getResources().getConfiguration());
        Locale.setDefault(locale);config.setLocale(locale);
        getBaseContext().createConfigurationContext(config);

    }  else {
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getBaseContext().getResources().updateConfiguration(config,
                getBaseContext().getResources().getDisplayMetrics());
    }

好的,我将N以下版本和N以上版本的代码分开:

  @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(updateBaseContextLocale(base));
    }

  private Context updateBaseContextLocale(Context context) {
       
     ...

        Locale locale = new Locale(lng);
        Locale.setDefault(locale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResourcesLocale(context, locale);
        }

        return updateResourcesLocaleLegacy(context, locale);
    }

    private Context updateResourcesLocale(Context context, Locale locale) {
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        return context.createConfigurationContext(configuration);
    }

    private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        configuration.locale = locale;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        return context;
    }
然后在onCreate中,我使用:

   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            updateBaseContextLocale(getBaseContext());
        }
if(Build.VERSION.SDK\u INT

通过这种方式,它最终适用于这两种场景。

首先,正如我们所讨论的,删除
attachBaseContext()
,并将其代码添加到
onCreate()

然后修改代码以获得新旧版本(Android-N以上)之间共享的
updateConfiguration()

在创建时添加以下代码

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Configuration config = new Configuration(getBaseContext().getResources().getConfiguration());
    Locale.setDefault(local);
    config.setLocale(local);
    getBaseContext().createConfigurationContext(config);

} else {
    Locale.setDefault(local);
    Configuration config = new Configuration();
    config.locale = myLocale;
}

Configuration config = new Configuration();
getBaseContext().getResources().updateConfiguration(config,
        getBaseContext().getResources().getDisplayMetrics());

与其在
attachBaseContext
中将代码写入
onCreate
中,不如将代码置于onCreate中,这样做有一定的帮助。如果我将代码置于onCreate中,该语言现在适用于旧设备,但现在它不适用于版本N和更高版本。你不能让updateConfiguration脱离条件,因为它不适用于更高版本(目前,它将一直工作到从更高版本中删除为止,因此我希望避免使用不推荐的代码)。因此,较新版本必须具有attachBaseContext,而较旧版本必须具有attachBaseContext。只有这样,它现在才能工作。