Android - Определение локали по умолчанию - PullRequest
0 голосов
/ 09 октября 2018

Я разрабатываю двуязычное приложение для 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?

1 Ответ

0 голосов
/ 09 октября 2018

Я не знаю, есть ли другие варианты или нет, один из способов - сделать это программно.В соответствии с отличным решением Рикардо , я создал следующий класс для изменения значения по умолчанию 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)));
}

Обновление

Использование этой выдающейся записи Мне удалосьнайти предоставленные языки автоматически.Поэтому вам больше не придется жестко кодировать it, de или другие предоставленные переводы всякий раз, когда вы добавляете новый ресурс в ресурсы.

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;
}
}
...