在运行时更改语言环境?

时间:2012-11-01 16:54:37

标签: android localization

我们有一个Android应用程序,可用作远程PC程序的客户端。我们想添加一个功能,以便PC可以指示Android应用程序在运行时更改其语言环境,即启动应用程序;把它与PC通信;一段时间后,PC告诉应用程序切换到西班牙语或中文。

我们已经为各自的区域设置了所有布局和字符串资源。我们的应用程序是用户看到的唯一应用程序,因此如果设备的其余部分保留为英语则无关紧要。

Change language programmatically in Android上有另一个帖子,但似乎没有得出结论。

我可以。 。 。

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

。 。 。在 setContentView()之前的 onCreate()中,但如果我想在屏幕启动并运行后更改语言环境,则无法提供帮助。有没有办法在Activity已经运行后重新加载内容视图?所以 有任何实用的方法可以动态地更改语言环境,或者我必须告诉我的老板除了在启动应用程序之前将整个设备设置为新的语言环境之外无法完成?

4 个答案:

答案 0 :(得分:17)

自API 11起,您可以使用recreate,因此可以在您的活动中使用此方法:

private void restartInLocale(Locale locale)
{
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    Resources resources = getResources();
    resources.updateConfiguration(config, resources.getDisplayMetrics());
    recreate();
}

答案 1 :(得分:3)

您可以启动活动的新实例并退出旧实例。这是一个完整的(未经测试的)示例,您可以如何存储任何所需的语言并重新启动您的应用程序。您只需使用您喜欢的语言拨打restartInLanguage

public class YourMainActivity extends Activity {
    private static final String APP_SHARED_PREFS = "com.example.test";
    private SharedPreferences settings;
    private Editor editor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        settings=getSharedPreferences(APP_SHARED_PREFS, Activity.MODE_PRIVATE);
        editor=settings.edit();

        Locale locale = new Locale(settings.getString("lang", "default-lang"));
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getResources().updateConfiguration(config, getResources().getDisplayMetrics());

        // your stuff...
    }

    public void restartInLanguage(String lang) {
        editor.putString("lang", lang);
        editor.commit();
        Intent intent = getIntent();
        finish();
        startActivity(intent);
    }

    // ...
}

答案 2 :(得分:1)

我已将@weston和@rekire(均+1)合并,并将其扩展到处理此用例:

  • ActivityA => ActivityB => SettingsActivity-changeLocale

changeLocale SettingsActivity之后,还应重新创建父活动ActivityAActivityB以反映新的区域设置。

我的解决方案:ActivityA和ActivityB继承自LocalizedActivity,检查onResume区域设置是否已更改,并在必要时触发recreate()

因此,从LocalizedActivity继承的每个活动都会自动处理应用特定的区域设置更改。

/**
 * An activity that can change the locale (language) of its content.
 *
 * Inspired by http://stackoverflow.com/questions/13181847/change-the-locale-at-runtime
 *
 * Created by k3b on 07.01.2016.
 */
public class LocalizedActivity extends Activity {
    /** if myLocale != Locale.Default : activity must be recreated in on resume */
    private Locale myLocale = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        fixLocale(this);
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Locale has changed by other Activity ?
        if ((myLocale != null) && (myLocale.getLanguage() != Locale.getDefault().getLanguage())) {
            myLocale = null;
            recreate();
        }
    }

    /**
     * Set Activity-s locale to SharedPreferences-setting.
     * Must be called before onCreate
     * @param context
     */
    public static void fixLocale(Context context)
    {
        final SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(context);
        String language = prefs.getString(Global.PREF_KEY_USER_LOCALE, "");
        Locale locale = Global.systemLocale; // in case that setting=="use android-locale"
        if ((language != null) && (!language.isEmpty())) {
            locale = new Locale(language); // overwrite "use android-locale"
        }

        if (locale != null) {
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            Resources resources = context.getResources();
            resources.updateConfiguration(config, resources.getDisplayMetrics());
            // recreate();

            if (context instanceof LocalizedActivity) {
                ((LocalizedActivity) context).myLocale = locale;
            }
        }
    }
}

以下是LocalizedActivity.java

中使用的SettingsActivity.javaA Photo Manager project的来源

答案 3 :(得分:0)

解决方案是在设置语言环境后,在onResume方法的每个活动中使用setContentView和controlLanguage(您也可以从Global类中调用此方法)方法。 例如:

@Override
    public void onClick(View v) {
        SharedPreferences.Editor editor;
        editor = sharedPref.edit();
        Configuration config = new Configuration(getBaseContext().getResources().getConfiguration());
        String language = "";
        switch (v.getId()){
            case R.id.turkceButton:
                editor.putString("language", "tr");
                language="tr";
                break;
            case R.id.englishButton:
                editor.putString("language", "en");
                language="en";
                break;
        }
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        config.locale = locale;
        getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
        editor.commit();


@Override
    protected void onResume() {
        super.onResume();
        controlLanguage(getApplicationContext(), getResources());
        setContentView(R.layout.main);
    }

public void controlLanguage(Context context, Resources res){
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
        String language = sharedPref.getString("language","en");
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        res.getConfiguration().locale = locale;
        res.updateConfiguration(res.getConfiguration(), res.getDisplayMetrics());
    }