以编程方式更改 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'
    }