无法使用Oreo android更改我的应用程序的语言 [英] Can't change the language of my app with Oreo android

查看:88
本文介绍了无法使用Oreo android更改我的应用程序的语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(编辑)

我使用了一种更改语言环境的解决方案来更改我的应用程序的语言,但它在oreo中不起作用.它可以在我的三星S4上正常运行,但不能在我的S9上运行.

I used a solution for locale change to change the language of my app and it is not working in oreo. It's working perfectly on my samsung S4, but not on my S9.

所以我正在执行以下语言环境更改:

   public void initAppLanguages(Context context, String lang){
        PreferenceUtil.setSelectedLanguageId(lang);
        LocaleUtils.setLocale(context, lang );
        MyApplication.reouvrir=1;
        Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
        this.finishAffinity();
        finish();
        startActivity(i);


    }

我的LocaleUtils类:

public class LocaleUtils {

    @Retention(RetentionPolicy.SOURCE)
    @StringDef({ENGLISH, FRENCH, SPANISH})
    public @interface LocaleDef {
        String[] SUPPORTED_LOCALES = {ENGLISH, FRENCH, SPANISH};
    }

    public static final String ENGLISH = "en";
    public static final String FRENCH = "fr";
    public static final String SPANISH = "es";


    public static void initialize(Context context) {
        setLocale(context, ENGLISH);
    }

    public static void initialize(Context context, @LocaleDef String defaultLanguage) {
        setLocale(context, defaultLanguage);
    }


    public static boolean setLocale(Context context, @LocaleDef String language) {
        return updateResources(context, language);
    }

    private static boolean updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        context.createConfigurationContext(configuration);
        configuration.locale = locale;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        return true;
    }
}

我的PreferenceUtil类:

public class PreferenceUtil {
    private static SharedPreferences getDefaultSharedPreference(Context context) {
        if (PreferenceManager.getDefaultSharedPreferences(MyApplication.getInstance().getApplicationContext()) != null)
            return PreferenceManager.getDefaultSharedPreferences(MyApplication.getInstance().getApplicationContext());
        else
            return null;
    }

    public static void setSelectedLanguageId(String id){
        final SharedPreferences prefs = getDefaultSharedPreference(MyApplication.getInstance().getApplicationContext());
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString("app_language_id", id);
        editor.apply();
    }

    public static String getSelectedLanguageId(){
        return getDefaultSharedPreference(MyApplication.getInstance().getApplicationContext())
                .getString("app_language_id", "en");
    }
}

子活动中的语言环境更改如下:

MyApplication.initAppLanguage(mContext);

我做错了什么?为什么在奥利奥(Oreo)中不起作用?

What am I doing wrong? Why is it not working in Oreo?

推荐答案

请按照以下步骤操作:

注意:我假设您在values文件夹中为不同的英语,西班牙语和法语创建了不同的字符串文件. (即res目录中每个values-en,values-es,values-fr文件夹中的strings.xml文件)

添加此文件: LocaleHelper.java

package com.test;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.LocaleList;
import android.preference.PreferenceManager;
import java.util.Locale;

public class LocaleHelper {

private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";

public static Context onAttach(Context context) {
    String lang = getPersistedData(context, Locale.getDefault().getLanguage());
    return setLocale(context, lang);
}

public static Context onAttach(Context context, String defaultLanguage) {
    String lang = getPersistedData(context, defaultLanguage);
    return setLocale(context, lang);
}

public static String getLanguage(Context context) {
    return getPersistedData(context, Locale.getDefault().getLanguage());
}

public static Context setLocale(Context context, String language) {
    persist(context, language);

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

    return updateResourcesLegacy(context, language);
}

private static String getPersistedData(Context context, String defaultLanguage) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}

private static void persist(Context context, String language) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = preferences.edit();

    editor.putString(SELECTED_LANGUAGE, language);
    editor.apply();
}

@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);

    Configuration configuration = context.getResources().getConfiguration();
    LocaleList localeList = new LocaleList(locale);
    localeList.setDefault(localeList);
    configuration.setLocales(localeList);

    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Resources resources = context.getResources();

    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;

    resources.updateConfiguration(configuration, resources.getDisplayMetrics());

    return context;
}
}

添加文件: LanguageUtil.java

package com.test;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.util.Log;

import java.util.Locale;

public class LanguageUtil {
public static void changeLanguageType(Context context, Locale localelanguage) {
    Log.i("=======", "context = " + context);
    Resources resources = context.getResources();
    DisplayMetrics dm = resources.getDisplayMetrics();
    Configuration config = resources.getConfiguration();
    // Application user selects language
    // reference https://developer.android.com/reference/android/content/res/Configuration.html
    if (VersionUtils.isAfter24()) {
        config.setLocale(localelanguage);
    } else {
        config.locale = localelanguage;
        resources.updateConfiguration(config, dm);
    }
}

public static Locale getLanguageType(Context context) {
    Log.i("=======", "context = " + context);
    Resources resources = context.getResources();
    Configuration config = resources.getConfiguration();
    // Application user selects language
    if (VersionUtils.isAfter24()) {
        return config.getLocales().get(0);
    } else {
        return config.locale;
    }
}
}

添加文件: MyContextWrapper.java

package com.test;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.LocaleList;

import java.util.Locale;

public class MyContextWrapper extends ContextWrapper {

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

@TargetApi(Build.VERSION_CODES.N)
public static ContextWrapper wrap(Context context, Locale newLocale) {
    Resources res = context.getResources();
    Configuration configuration = res.getConfiguration();

    if (VersionUtils.isAfter24()) {
        configuration.setLocale(newLocale);

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

        context = context.createConfigurationContext(configuration);

    } else if (VersionUtils.isAfter17()) {
        configuration.setLocale(newLocale);
        context = context.createConfigurationContext(configuration);

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

    return new ContextWrapper(context);
}
}

添加文件: VersionUtils.java

package com.test;

import android.os.Build;
import android.support.annotation.RequiresApi;

public final class VersionUtils {

@RequiresApi(Build.VERSION_CODES.N_MR1)
public static boolean isAfter25() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1;
}

@RequiresApi(Build.VERSION_CODES.N)
public static boolean isAfter24() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
}

public static boolean isAfter23() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}

public static boolean isAfter22() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1;
}

public static boolean isAfter21() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}

public static boolean isAfter20() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH;
}

public static boolean isAfter19() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
}

public static boolean isAfter18() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
}

public static boolean isAfter17() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
}

public static boolean isAfter16() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
}

public static boolean isAfter14() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

public static boolean isAfter13() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2;
}

public static boolean isAfter11() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
}

public static boolean isAfter9() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
}

public static boolean isAfter8() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}

public static boolean isAfter5() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR;
}
}

现在创建Prefs文件: Prefs.kt (这是Kotlin类文件) 注意:您可以使用自己的首选项创建和重新生成代码.

Now Create Prefs file: Prefs.kt (This is Kotlin class file) Note: You can use your own preference creation and retrivation code.

打包com.test

package com.test

import android.content.Context
import android.content.SharedPreferences
import android.content.SharedPreferences.Editor

class Prefs private constructor(private val context: Context) {
private val prefranceName = "testPrefs"

companion object {

    private fun getPrefs(context: Context): SharedPreferences {
        return context.getSharedPreferences(context.packageName, 0)
    }

    fun clearDefaultShared(key: String, context: Context) {
        val e = getPrefs(context).edit()
        e.remove(key)
        e.apply()
    }

    fun setString(key: String, sunDefult: String, context: Context) {
        val e = getPrefs(context).edit()
        e.putString(key, sunDefult)
        e.apply()
    }

    fun getString(key: String, sunDefult: String, context: Context): String? {
        return getPrefs(context).getString(key, sunDefult)
    }

    fun clearAll(context: Context) {
        val editor = getPrefs(context).edit()
        editor.clear()
        editor.commit()
    }
}
}

现在创建一个TestApp类,它扩展了Application类. 这将用于保存应用重新启动时要应用的最后选择的语言. 注意:别忘了将此应用程序类名称"TestApp"添加到标签中的AndroidManifest.xml.

Now create one class TestApp which extends the Application class. This will use to save the last selected language you want to apply when app restarts. Note: don't forget to add this app class name "TestApp" to AndroidManifest.xml in tag.

添加文件: TestApp.kt

package com.test

import android.app.Application
import com.test.LanguageUtil
import com.test.Prefs
import java.util.*

class TestApp : Application() {

override fun onCreate() {
    super.onCreate()
    dbAdapter = DBAdapter(applicationContext)
    dbAdapter.openDataBase()

    // Set Language Because Local will not be saved every time the app restarts after it is completely logged out
    var languageType = Prefs.getString("languageType", "en", this@TestApp).toString()


    if (languageType == "fr") {
        LanguageUtil.changeLanguageType(this, Locale.FRENCH)
    } else if (languageType == "es") {
        LanguageUtil.changeLanguageType(this, Locale("es",""))
    } else {
        LanguageUtil.changeLanguageType(this, Locale.ENGLISH)
    }

}
}

现在在每个活动中,添加以下代码以应用更改的语言.

Now in each activity, add the code below to apply the changed language.

这是Kotlin代码:

This is Kotlin code:

override fun attachBaseContext(newBase: Context) {
    var languageType = Prefs.getString("languageType", "en", newBase).toString()
    super.attachBaseContext(MyContextWrapper.wrap(newBase, Locale(languageType, "")))
}

当您选择其他语言时,请使用以下代码:

When you select the different language, use this code:

LanguageUtil.changeLanguageType(this@MainActivity, Locale.ENGLISH) // for englsih
LanguageUtil.changeLanguageType(this@MainActivity, Locale("es","")) // for spanish
LanguageUtil.changeLanguageType(this@MainActivity, Locale.FRENCH)// for french

,然后还将其存储在sharedpreference中.

and after also store it in sharedpreference.

请记住:如果您在当前活动中更改语言,而您在该语言中看不到更改,因为您需要重新启动活动以查看更改,但是在此当前活动之后打开活动,您将看到更改.

Remember: If you change language in current Activity and you will not see the language change in that, because you need to restart activity to see the changes but activity opened after this current activity you will see the changes.

如果您在同一活动中调用recreate(),它将使屏幕闪烁,因此请勿使用recreate()函数.

If you call recreate() in the same activity, it will blink the screen, so do not use the recreate() function.

我有一个解决方案(不是适当的解决方案,但是我可以说它是补丁程序,并且工作得很完美). 为了显示当前活动的变化,您需要在默认的string.xml中创建所有的英语,西班牙语和法语字符串,并在用户选择其他语言时在当前活动中将其设置为运行时.

I have one solution (not proper solution but I can say it is patch and it is worked perfect). For displaying changes in current activity you need to create all the english, spanish and french string in default strings.xml and set it runtime in current activity when the user selects a different language.

这篇关于无法使用Oreo android更改我的应用程序的语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆