Получить строку из локали по умолчанию, используя строку в определенной локали

Хорошо, я знаю, название звучит безумно:)

Вот что я хочу. Мое приложение локализовано для пользователя устройства, но информация, которую я отправляю обратно на сервер, должна быть полностью английской. Мой язык приложения по умолчанию английский.

Например, у меня есть массив:

  • яблоки
  • апельсины
  • персики

Я локализовал массив:

  • Яблоки
  • Апельсины
  • Персики

Когда российский пользователь видит список и выбирает пару пунктов - мне нужно получить соответствующие английские версии.

Я предполагаю, что мой ответ сводится к тому, как сделать getString() и передать локаль? Или как получить массив в определенной локали?

8 ответов

Решение

Вы должны идентифицировать элемент по чему-то еще, например по идентификатору или даже по английскому имени.

Невозможно получить исходную строку для данной локализованной строки. Одна из причин заключается в том, что локализация строк не является транзитивной функцией, но есть много других причин, по которым это не очень хорошее направление.

Приведенный ниже код извлечет локализованную строку для польского языка, даже если локаль по умолчанию на устройстве отличается:

Configuration conf = getResources().getConfiguration();
conf.locale = new Locale("pl");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources resources = new Resources(getAssets(), metrics, conf);
/* get localized string */
String str = resources.getString(R.string.hello);

Я надеюсь, что это также относится к другим типам ресурсов, таким как массив, поэтому достаточно заменить "pl" на "en"...

Если вы используете JB 2.2.x или выше (в основном API >= 17), вы можете использовать createConfigurationContext do:

public String translate(Locale locale, int resId) {  
    Configuration config = new Configuration(context.getResources().getConfiguration()); 
    config.setLocale(locale);   
    return context.createConfigurationContext(config).getText(resId);
}

Этот не имеет побочных эффектов: API17 и выше

Configuration config = new Configuration(context.getResources().getConfiguration()); 
config.setLocale(locale);   
return context.createConfigurationContext(config).getResources();

Эта "принудительная" локализация не сработает, если на ваших устройствах нет требуемой локали.

Не могу доказать это "просто так", но сейчас я борюсь с такой проблемой, когда я заставляю ресурс находиться в локали / языке, который не установлен на устройстве (на Android 2.3.3), и все еще получаю строки из values-en (англ.) ресурсов.

На других устройствах, когда вы вводите локаль (но не обязательно в качестве текущей локали), вы получите правильные ресурсы.

Я считаю, что это безопасный путь (не касаясь текущей конфигурации):

Configuration conf = new Configuration();
conf.setToDefaults();   // That will set conf.locale to null (current locale)
// We don't want current locale, so modify it
conf.locale = new Locale("");   // Or conf.locale = Locale.ROOT for API 9+
                                // or conf.setLocale(Locale.ROOT) for API 14+
// Since we need only strings, we can safely set metrics to null
Resources rsrcDflt = new Resources(getAssets(), null, conf);
String apples = srcDflt.getString(R.string.apples); // Got it at last!

Я объединил два подхода, необходимые для работы на всех версиях Android. Смотрите мой ответ здесь.

У меня была та же проблема с ListPreference, которая сохраняла настройки "имя штата" и "фигура тела". ListPreference получает свои значения и записи из массива, сохраненного в локализованных папках "значений". Значения списка были одинаковыми (на английском языке), но записи были локализованы (на английском и иврите).

Я наконец-то использовал следующий код:

public void OnSharedPreferenceChanged (SharedPreferences sharedPreferences, String key)
{
    SharedPreferences.Editor editor = sharedPreferences.edit();
    Preference pref = settings.findPreference(key);
    pref.setSummary(sharedPreferences.getString(key, ""));

    if (key.equalsIgnoreCase(PREF_STATE) 
        || key.equalsIgnoreCase(PREF_BODY_FIGURE))
    {
        editor.putString(key, ((ListPreference) pref).getValue());
        editor.commit();
    }
}

Таким образом, предпочтение всегда показывало локализованную строку пользователю (в качестве сводки), но сохраняло английскую строку в памяти настроек, которая в конечном итоге была отправлена ​​на сервер.

Другие вопросы по тегам