在 Android 中使用 Unicode
Posted
技术标签:
【中文标题】在 Android 中使用 Unicode【英文标题】:Use Unicode in Android 【发布时间】:2020-11-18 23:23:26 【问题描述】:在使用 android 应用程序时,我观察到 Unicode 是 API 响应的一部分:
"msg_txt":"Laurent Ruquier et l'\\u00e9quipe"
在 Android 端,我有一个简单的TextView
,我必须通过将 Unicode 转换为文本来显示实际文本。
【问题讨论】:
无需转换,自动显示unicode后面的文字 是的,但是正如您在上面的 JSON 中看到的那样,它会按原样显示。 ok 尝试从 \\ 中删除一个 \ 你只有一个转义字符串,而不是一个 unicode 字符串。只是“逃避”它。一个普通的 JSON 阅读器应该可以做到,或者有各种库。 【参考方案1】:由于响应中已经包含 unicode 字符,因此您需要对其进行解析。我不是重新发明***的朋友,所以你通常会使用像 apache commons unescapeJava 这样的东西。如果您决定将其作为依赖项添加到您的 gradle 构建中,请确保正确配置您的 R8 收缩 (see here),否则您将在发布构建中添加大量方法和类。这也会大大减慢调试构建速度,所以要小心。
虽然上述方法实际上不仅仅是替换转义的 unicode 字符,但如果您只需要此功能并且不想为这段代码添加 apache 依赖项,我们可以查看它们的实现 here 和here。我提取了相关部分并将其转换为 Kotlin,只是为了好玩:
val inputString = "Laurent Ruquier et l'\\u00e9quipe"
val unescaped = translate(inputString)
//this is the main method that does the actual conversion on a character
// by character basis.
fun translate(input: CharSequence, index: Int, out: Writer): Int
if (input[index] == '\\' && index + 1 < input.length && input[index + 1] == 'u')
// consume optional additional 'u' chars
var i = 2
while (index + i < input.length && input[index + i] == 'u')
i++
if (index + i < input.length && input[index + i] == '+')
i++
if (index + i + 4 <= input.length)
// Get 4 hex digits
val unicode = input.subSequence(index + i, index + i + 4)
try
val value = unicode.toString().toInt(16)
out.write(value)
catch (nfe: NumberFormatException)
throw IllegalArgumentException("Unable to parse unicode value: $unicode", nfe)
return i + 4
throw IllegalArgumentException(
"Less than 4 hex digits in unicode value: '"
+ input.subSequence(index, input.length)
+ "' due to end of CharSequence"
)
return 0
//helper method for working directly with strings
fun translate(input: CharSequence): String
val writer = StringWriter(input.length * 2)
translate(input, writer)
return writer.toString()
// this goes through the actual char sequence and passes every
// single char to the unicode transformer and swallows consumed chars
fun translate(input: CharSequence, out: Writer)
var pos = 0
val len = input.length
while (pos < len)
val consumed = translate(input, pos, out)
if (consumed == 0)
// inlined implementation of Character.toChars(Character.codePointAt(input, pos))
// avoids allocating temp char arrays and duplicate checks
val c1 = input[pos]
out.write(c1.toInt())
pos++
if (Character.isHighSurrogate(c1) && pos < len)
val c2 = input[pos]
if (Character.isLowSurrogate(c2))
out.write(c2.toInt())
pos++
continue
// contract with translators is that they have to understand codepoints
// and they just took care of a surrogate pair
for (pt in 0 until consumed)
pos += Character.charCount(Character.codePointAt(input, pos))
请注意,这实际上是简单的框架,可能需要针对实际生产用途进行一些调整。如果例如您的输入将包含两个反斜杠(如val inputString = "Laurent Ruquier et l'\\\\u00e9quipe"
),您需要稍微修改一下方法。
【讨论】:
以上是关于在 Android 中使用 Unicode的主要内容,如果未能解决你的问题,请参考以下文章
如何在 android 应用程序中使用 OSM 地图。?有啥教程可以学习在android中使用OSM吗?
在 Android 中使用 Intent 在活动中传递 android 位图数据
无法在 Android 中使用 Android Crop 图像裁剪库