安卓系统-定义默认语言环境

3

我正在开发一款双语Android应用程序,支持德语和意大利语。
目前我有一个包含意大利语字符串的values-it和一个包含德语字符串的values文件夹。 除非您的设备同时安装了德语和意大利语,否则这种做法是可行的。如果你的设备同时安装了德语和意大利语,那么应用程序将一直以意大利语运行,根据以下计算:

User Setting: de_DE, it_IT
App Resources: default(en), it

Try de_DE -> fail
Try de -> fail
Try it_IT -> fail
Try it -> Success

这可能是因为默认设置被隐式地视为values-en,而在我的情况下它实际上是values-de

有没有办法告诉Android,我的应用程序默认语言环境是de而不是en

2个回答

3

我不知道是否有其他的选择,一个方法是通过编程实现。根据Ricardo提供的好的解决方案,我创建了以下类来更改默认的Local:

public class LocaleHelper {

public static Context onAttach(Context context) {
    String lang = Locale.getDefault().getLanguage();
    if(lang.equals("it") || lang.equals("de"))
        return context;
    String locale = "de";
    return setLocale(context, locale);
}

private static Context setLocale(Context context, String localeSpec) {
    Locale locale;
    if (localeSpec.equals("system")) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            locale = Resources.getSystem().getConfiguration().getLocales().get(0);
        } else {
            locale = Resources.getSystem().getConfiguration().locale;
        }
    } else {
        locale = new Locale(localeSpec);
    }
    Locale.setDefault(locale);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return updateResources(context, locale);
    } else {
        return updateResourcesLegacy(context, locale);
    }
}

@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, Locale locale) {
    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    configuration.setLayoutDirection(locale);

    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();

    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        configuration.setLayoutDirection(locale);
    }

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

    return context;
}
}

您应该在您的Activity类中使用它:
@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(LocaleHelper.onAttach(base));
}

如果您正在使用uk.co.chrisjenx.calligraphy来更改字体,您应该按照以下步骤操作:
@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(LocaleHelper.onAttach(base)));
}

更新

使用这篇杰出的帖子,我成功自动找到了提供的语言。因此,当您将新的翻译添加到资源中时,您不再需要硬编码 itde或其他提供的翻译。

public class LocaleHelper {

public static Context onAttach(Activity context) {
    Set<String> providedLangs = getProvidedLanguages(context);
    String lang = Locale.getDefault().getLanguage();
    if(providedLangs.contains(lang))
        return context;
    String locale = "de";
    return setLocale(context, locale);
}

private static Set<String> getProvidedLanguages(Activity activity){
    DisplayMetrics metrics = new DisplayMetrics();
    activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
    Resources r = activity.getResources();
    Configuration c = r.getConfiguration();
    String[] loc = r.getAssets().getLocales();
    Set<String> providedLangs = new HashSet<String>();
    for (int i = 0; i < loc.length; i++) {
        Timber.e("LOCALE: " +  i + ": " + loc[i]);

        c.locale = new Locale(loc[i]);
        Resources res = new Resources(activity.getAssets(), metrics, c);
        String s1 = res.getString(R.string.app_name);
        c.locale = new Locale("");
        Resources res2 = new Resources(activity.getAssets(), metrics, c);
        String s2 = res2.getString(R.string.app_name);

        if(!s1.equals(s2)){
            if(!providedLangs.contains(loc[i]))
                providedLangs.add(loc[i]);
        }
    }

    return providedLangs;
}

private static Context setLocale(Context context, String localeSpec) {
    Locale locale;
    if (localeSpec.equals("system")) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            locale = Resources.getSystem().getConfiguration().getLocales().get(0);
        } else {
            locale = Resources.getSystem().getConfiguration().locale;
        }
    } else {
        locale = new Locale(localeSpec);
    }
    Locale.setDefault(locale);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return updateResources(context, locale);
    } else {
        return updateResourcesLegacy(context, locale);
    }
}

@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, Locale locale) {
    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    configuration.setLayoutDirection(locale);

    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();

    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        configuration.setLayoutDirection(locale);
    }

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

    return context;
}
}

谢谢您的回答,我会尽快尝试。 - Robert P
我刚试了一下,但它似乎现在只使用我设置的语言。相反,我想要的是,如果意大利语是首选语言,则使用意大利语,否则使用德语。 - Robert P
@Springrbua,我刚刚更新了onAttach方法,请再试一次。 - a.toraby
@Springrbua 我认为值得看一下更新的帖子 ;) - a.toraby
感谢您的努力。我可能会坚持当前的情况,因为这通常不是一个大问题,而提供的解决方案更像是一种变通方法。我只是认为Android框架提供了一个简单直接的解决方案。 - Robert P

0

20210715 这对我似乎很有效。重点是要确定标识语言环境的语句,并且必须提供上下文。

///this function was called from a FRAGMENT and works fine .
////  dateLong = TimeConvert.tcConvertDateToLong(..........,requireContext()
fun tcConvertDateToLong(
        yyyy: Int, MM: Int, dd: Int, HH: Int, mm: Int,context: Context
): Long {
    val mTag64="TimeConvert_tcConvertDateToLong"
    val date:String
    date=yyyy.toString() + "." + MM.toString() + "."+ dd.toString() +" "+ HH.toString() + ":" + mm.toString()
    ////////////-------------------------------------------------------------
    val locale = getLocales(context.getResources().getConfiguration()).get(0)
    //////////-------------------------------------------------------------
    val df = SimpleDateFormat("yyyy.MM.dd HH:mm",locale)
    return try {
        df.parse(date)!!.time
    }  catch (  e: ParseException){
        java.lang.System.currentTimeMillis()
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接