资产文件的本地化

时间:2011-03-25 02:32:20

标签: android localization

我在assets文件夹中有几个html文件。我该如何本地化它们?我唯一的选择是根据区域设置选择一些硬编码来选择正确的文件吗?

6 个答案:

答案 0 :(得分:57)

这不是直接支持,但这是我所做的......

按国家/地区代码将文件分成几组(就像您对常规资源文件所做的那样),然后在每个本地化的string.xml文件中创建一个本地化字符串,称为“prefix”(前缀为“en”) “例如英语。”

然后,当您构建资产文件名时,请使用getString("prefix") + "-" + "<name-of-asset->

之类的内容

至少上述一些变体对你有用。

答案 1 :(得分:31)

如果您要本地化HTML文件,只需将其放在 res / raw-&lt; language&gt; /filename.html 下(其中&lt; language&gt; = en,es,fr,it等等)然后使用资源ID R.raw.filename 从代码中访问它。框架将根据区域设置选择正确的文件。

答案 2 :(得分:30)

将您的文件放入具有本地后缀的assets文件夹中。为每个文件定义一个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));
  }
}

答案 3 :(得分:2)

将文件放在raw-LOCALE文件夹中会自动选择正确的位置,但如果在webView中加载这些文件,则在使用Proguard进行模糊处理后,路径将被破坏。

Proguard Breaks Android WebView, Why?

然后唯一的解决方案是使用assets文件夹并使用file-LOCALE并选择正确的文件。

答案 4 :(得分:1)

尝试使用assets-ja进行本地化是行不通的,因为遗憾的是这些不是资源文件。最好的选择是使用正确的语言环境以编程方式进行本地化。或者,HTML文件的内容只是纯文本。如果它适合您的项目,您可以尝试将此字符串存储为新strings.xml文件夹的myHtmlText.xml(或您自己的values-ja?)文件中的条目。

答案 5 :(得分:1)

每个国家/地区代码使用一个文件的替代方法(如Andrew White'sPJ_Finnegan's答案中所述)是仅定义HTML一次(例如在assets文件夹中)并使用{其中有{1}} ID,如此

@string

将资源加载到字符串后,您可以将其内容传递给<html> <body> <p>@string/message_text</p> </body> </html>

replaceResourceStrings()

这种方法的好处是你必须只指定一次HTML的结构并使用android's localization mechanism。此外,它允许递归引用strings.xml中的字符串,Context.getResources()不支持。例如:

/**
 * 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 (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会有更好的性能。

有关使用此代码将HTML从资源文件转换为“可设置样式”<?xml version="1.0" encoding="utf-8"?> <resources> <string name="message_text">Some string @string/another_one.</string> </resources> (使用Kuitsi's TagHandler)的示例,可以在CharSequence中显示{{3} }}