以程式設計方式更改 android 應用程式的語言環境

在上面的示例中,你瞭解瞭如何本地化應用程式的資源。以下示例說明如何在應用程式中更改應用程式區域設定,而不是從裝置更改。要僅更改應用程式區域設定,可以使用以下區域設定實用程式。

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import android.view.ContextThemeWrapper;

import java.util.Locale;

/**
 * Created by Umesh on 10/10/16.
 */
public class LocaleUtils {

    private static Locale mLocale;

    public static void setLocale(Locale locale){
        mLocale = locale;
        if(mLocale != null){
            Locale.setDefault(mLocale);
        }
    }

    public static void updateConfiguration(ContextThemeWrapper wrapper){
        if(mLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
            Configuration configuration = new Configuration();
            configuration.setLocale(mLocale);
            wrapper.applyOverrideConfiguration(configuration);
        }
    }

    public static void updateConfiguration(Application application, Configuration configuration){
        if(mLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){
            Configuration config = new Configuration(configuration);
            config.locale = mLocale;
            Resources res = application.getBaseContext().getResources();
            res.updateConfiguration(configuration, res.getDisplayMetrics());
        }
    }

    public static void updateConfiguration(Context context, String language, String country){
        Locale locale = new Locale(language,country);
        setLocale(locale);
        if(mLocale != null){
            Resources res = context.getResources();
            Configuration configuration = res.getConfiguration();
            configuration.locale = mLocale;
            res.updateConfiguration(configuration,res.getDisplayMetrics());
        }
    }

    public static String getPrefLangCode(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context).getString("lang_code","en");
    }

    public static void setPrefLangCode(Context context, String mPrefLangCode) {

        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
        editor.putString("lang_code",mPrefLangCode);
        editor.commit();
    }

    public static  String getPrefCountryCode(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context).getString("country_code","US");
    }

    public static void setPrefCountryCode(Context context,String mPrefCountryCode) {

        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
        editor.putString("country_code",mPrefCountryCode);
        editor.commit();
    }
}

從 Application 類初始化使用者首選的語言環境。

public class LocaleApp extends Application{

    @Override
    public void onCreate() {
        super.onCreate();

        LocaleUtils.setLocale(new Locale(LocaleUtils.getPrefLangCode(this), LocaleUtils.getPrefCountryCode(this)));
        LocaleUtils.updateConfiguration(this, getResources().getConfiguration());
    }
}

你還需要建立基本活動並將此活動擴充套件到所有其他活動,以便你可以將應用程式的區域設定僅更改為一個位置,如下所示:

public abstract class LocalizationActivity extends AppCompatActivity {

    public LocalizationActivity() {
        LocaleUtils.updateConfiguration(this);
    }

    // We only override onCreate
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

注意:始終在建構函式中初始化語言環境。

現在你可以使用 LocalizationActivity,如下所示。

public class MainActivity extends LocalizationActivity {

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

    }
}

注意:以程式設計方式更改應用程式的區域設定時,需要重新啟動活動才能獲得區域設定更改的效果為了正確使用此解決方案,你可以在應用程式啟動時使用共享首選項中的區域設定,在你的 Manifest.xml 中使用 android:name=".LocaleApp"

有時 Lint 檢查器會提示建立釋出版本。要解決此類問題,請遵循以下選項。

第一:

如果要僅為某些字串禁用轉換,請將以下屬性新增到預設 string.xml

<string name="developer" translatable="false">Developer Name</string>

第二:

忽略資原始檔中所有缺少的轉換新增以下屬性它是字串檔案中 tools 名稱空間的 ignore 屬性,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources
  xmlns:tools="http://schemas.android.com/tools"
  tools:ignore="MissingTranslation" >
http://stackoverflow.com/documentation/android/3345/localization-with-resources-in-android#
  <!-- your strings here; no need now for the translatable attribute -->

</resources>

第三:

另一種禁用不可翻譯字串的方法

http://tools.android.com/recent/non-translatablestrings

如果你有大量不應翻譯的資源,可以將它們放在名為 donottranslate.xml 的檔案中,而 lint 會將所有資源都視為不可翻譯的資源。

第四:

你還可以在資原始檔中新增區域設定

<resources
xmlns:tools="http://schemas.android.com/tools"
    tools:locale="en" tools:ignore="MissingTranslation">

你還可以從 app / build.gradle 中禁用缺少 lint 的翻譯檢查

lintOptions {
        
        disable 'MissingTranslation'
    }