在 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吗?

如何在Mac中使用Android SDK

在 Android 中使用 Intent 在活动中传递 android 位图数据

无法在 Android 中使用 Android Crop 图像裁剪库

Android:如何在 Android 中使用 tensorflow lite 扩展图像的维度

如何在android中使用WCF服务?