Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

Поместите свои файлы в папку с локальным суффиксом. Определите ресурс 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));
  }
}

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

Альтернатива использованию одного файла для кода страны (как описано в Andrew White's и PJ_Finnegan) заключается в том, чтобы определить HTML только один раз (например, в папке assets) и использовать в нем @string ID, например

<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 resource strings (e.g.
 * <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 (e.g. 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 (e.g. 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 (используя Kuitsi TagHandler), который может отображаться в TextView см. TextUtil.