如何在 Android 资源中使用 unicode?

Posted

技术标签:

【中文标题】如何在 Android 资源中使用 unicode?【英文标题】:How to use unicode in Android resource? 【发布时间】:2013-05-23 02:39:37 【问题描述】:

我想在我的资源文件中使用this unicode 字符。

但无论我做什么,我都会以 dalvikvm 崩溃告终(用 android 2.3 和 4.2.2 测试):

W/dalvikvm( 8797): JNI WARNING: input is not valid Modified UTF-8: illegal start byte 0xf0
W/dalvikvm( 8797):              string: '????'
W/dalvikvm( 8797):              in Landroid/content/res/StringBlock;.nativeGetString:(II)Ljava/lang/String; (NewStringUTF)
E/dalvikvm( 8797): VM aborting
F/libc    ( 8797): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 8797 (cz.ipex...)

我在我的资源文件中尝试了这些版本:

<string name="geolocation_icon" translatable="false">&#x1f4e1;</string> <!-- html -->
<string name="geolocation_icon" translatable="false">\uD83D\uDCE1</string> <!-- escaped unicode -->
<string name="geolocation_icon" translatable="false">????</string> <!-- unicode character -->

请注意,在代码中的 Java String 中使用它可以正常工作:

final String geolocation_icon = "\uD83D\uDCE1";

【问题讨论】:

您是否尝试在 XML 文件中使用 UTF-8?使用hexdump,能确认编码为0xF0 0x9F 0x93 0xA1序列吗? 是的,是的,如果您查看上面的错误输出,您会发现它在抱怨它:input is not valid Modified UTF-8: illegal start byte 0xf0 【参考方案1】:

这样做

不要在 strings.xml 中保留有问题的表情符号

以编程方式添加它

<string name="hi_welcome_msg">Hi %1$s</string>

getString(R.string.hi_welcome_msg, user.getFullName() + " \uD83D\uDC4B" );

【讨论】:

【参考方案2】:

您的角色 (U+1F4E1) 不属于 Unicode BMP(基本多语言平面 - 范围从 U+0000U+FFFF)。

不幸的是,Android 对非 BMP 字符的支持非常弱(如果有的话)。 UTF-8 表示非 BMP 字符需要 4 个字节 (0xF0 0x9F 0x93 0xA1)。但是,Android UTF-8 解析器最多只能理解 3 个字节(参见 herehere)。

当您使用 UTF-16 这个字符的代理形式表示时,它适用于您:"\uD83D\uDCE1"。如果您能够在修改后的UTF-8(又名CESU-8)中编码每个代理UTF-16字符-总共需要6个字节(代理对的每个成员UTF-8中的3个字节),那么就有可能.但是,Android 也不明确支持CESU-8

因此,您当前的解决方案 - 在源代码中将此符号硬编码为代理 UTF-16 对似乎最简单,至少在 Android 开始完全支持非 BMP UTF-8 之前。

更新:这似乎在 Android 6.0 中得到了部分修复。 This commit 已合并到 Android 6 中,并允许在 XML 资源中存在 4 字节 UTF-8 字符。它不是完美的解决方案 - 它只会自动将 4 字节 UTF-8 转换为适当的代理对。但是,它允许将它们从源代码移动到 XML 资源中。遗憾的是,在您的应用程序停止支持除 6.0 及更高版本之外的任何 Android 版本之前,您无法使用此解决方案。

【讨论】:

这非常令人沮丧,因为它使 Class 文件比它需要的大得多。最好将这些 un​​icode 字符串分隔到 arrays.xmlstrings.xml 文件中。 @toobsco42:你可能想file a bug in Android bug database。 嗨,我有一个 xml 文件,其中包含“\uD83D\uDCE1”之类的代理对,但在尝试解析文件时出现错误,您能帮帮我吗? @SWAppDev:您可以在 Java 源代码中使用代理对,但不能在资源 XML 中使用。 此website 可让您计算代理对。

以上是关于如何在 Android 资源中使用 unicode?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android中使用unicode支持创建PDF

如何在 Android 的 TextView 中显示 Unicode 字符?

在 Android 中使用 Unicode

Android:如何动态翻转或旋转 unicode 字符

vs2010 mfc项目配置属性的字符集为Unicode和多字节时,两者转换后使用的控件外观不一样

unicode和多字节字符集的区别,该如何解决