Локализация файлов активов

У меня есть несколько html-файлов в папке с ресурсами. Как я могу их локализовать? Является ли мой единственный способ поставить некоторый жесткий код для выбора нужного файла на основе языка?

Это не поддерживается напрямую, но вот что я сделал …

Разделите свои файлы на группы по коду страны (например, что вы делаете для обычных файлов ресурсов), а затем создайте локализованную строку в каждом локализованном файле string.xml, называемом «префикс» (где префикс будет «en» для английского языка например).

Затем, когда вы создаете свои имена файлов ресурсов, просто используйте что-то вроде getString("prefix") + "-" + "<name-of-asset-> .

По крайней мере, некоторые изменения выше должны работать на вас.

Если вы хотите локализовать HTML-файл, вы можете просто поставить его под res / raw- <language> /filename.html (где <язык> = en, es, fr, it и т. Д.), Затем получить к нему доступ из вашего кода с помощью Идентификатор ресурса R.raw.filename . Структура будет выбирать правильный файл в соответствии с языковым стандартом.

Поместите свои файлы в папку с локальным суффиксом. Определите ресурс String 'myLocalizedFileName' для каждого файла и получите имя файла через R.string.myLocalizedFileName.

Пример:

Структура папок:

 assets/ assets/help.html assets/help_de.htlm 

Строковые ресурсы для каждого языка в res / values ​​/ strings.xml:

 <resource> <string name=helpFile>help.html</string> </resource> 

Вызов WebView:

 public class HelpActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { ... findViewById(R.id.helpWebView) .loadUrl("file:///android_asset/" + getString(R.string.helpFile)); } } 

Попытка локализовать с помощью assets-ja не будет работать, потому что, к сожалению, это не файлы ресурсов. Лучший вариант – локализовать программно, с правильной локалью. В качестве альтернативы, содержимое HTML-файла представляет собой простой текст. Если он соответствует вашему проекту, вы можете попытаться сохранить эту строку как запись в файле myHtmlText.xml (или ваш собственный myHtmlText.xml ?) Новой папки values-ja , например.

Помещение файлов в папку raw-LOCALE автоматически выберет правильное местоположение, но если вы загрузите эти файлы в пути webView, они будут повреждены после обфускации с помощью Proguard.

Proguard перерывает Android WebView, почему?

Тогда единственным решением является использование папки с ресурсами и использование файла-LOCALE и выбор правильных файлов.

Альтернативой использованию одного файла для кода страны (как описано в ответах Эндрю Уайта и PJ_Finnegan ) является определение HTML только один раз (например, в папке с assets ) и использование в @string идентификаторов @string , например

 <html> <body> <p>@string/message_text</p> </body> </html> 

После загрузки актива в строку вы можете передать свой контент replaceResourceStrings() :

 /** * Regex that matches a resource string such as <code>@string/a-b_c1</code>. */ private static final String REGEX_RESOURCE_STRING = "@string/([A-Za-z0-9-_]*)"; /** Name of the resource type "string" as in <code>@string/...</code> */ private static final String DEF_TYPE_STRING = "string"; /** * Recursively replaces resources such as <code>@string/abc</code> with * their localized values from the app's resource strings (eg * <code>strings.xml</code>) within a <code>source</code> string. * * Also works recursively, that is, when a resource contains another * resource that contains another resource, etc. * * @param source * @return <code>source</code> with replaced resources (if they exist) */ public static String replaceResourceStrings(Context context, String source) { // Recursively resolve strings Pattern p = Pattern.compile(REGEX_RESOURCE_STRING); Matcher m = p.matcher(source); StringBuffer sb = new StringBuffer(); while (m.find()) { String stringFromResources = getStringByName(context, m.group(1)); if (stringFromResources == null) { Log.w(Constants.LOG, "No String resource found for ID \"" + m.group(1) + "\" while inserting resources"); /* * No need to try to load from defaults, android is trying that * for us. If we're here, the resource does not exist. Just * return its ID. */ stringFromResources = m.group(1); } m.appendReplacement(sb, // Recurse replaceResourceStrings(context, stringFromResources)); } m.appendTail(sb); return sb.toString(); } /** * Returns the string value of a string resource (eg defined in * <code>values.xml</code>). * * @param name * @return the value of the string resource or <code>null</code> if no * resource found for id */ public static String getStringByName(Context context, String name) { int resourceId = getResourceId(context, DEF_TYPE_STRING, name); if (resourceId != 0) { return context.getString(resourceId); } else { return null; } } /** * Finds the numeric id of a string resource (eg defined in * <code>values.xml</code>). * * @param defType * Optional default resource type to find, if "type/" is not * included in the name. Can be null to require an explicit type. * * @param name * the name of the desired resource * @return the associated resource identifier. Returns 0 if no such resource * was found. (0 is not a valid resource ID.) */ private static int getResourceId(Context context, String defType, String name) { return context.getResources().getIdentifier(name, defType, context.getPackageName()); } 

Самое приятное в этом подходе заключается в том, что вы должны указывать структуру HTML только один раз и использовать механизм локализации Android . Кроме того, он позволяет рекурсивно ссылаться на строки в strings.xml, который не поддерживается Context.getResources() . Например:

 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="message_text">Some string @string/another_one.</string> </resources> 

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

Для примера, который использует этот код для преобразования HTML из файла активов в «стилизованный» CharSequence (с помощью TagHandler Kuitsi ), который может отображаться в TextView см. TextUtil .