上一篇我们介绍了WiFi SSID自动识别问题,用到了ICU库,最近终于在Android 7.1系统完整实现并验证通过,WiFi SSID中文繁体和简体识别以及连接全部解决,但是调试过程中却发现了JAVA核心库ICU的BUG.
在修改完Android framework对SSID原始内容自动识别问题,调用JAVA ICU库的CharsetDetector类,刚开始测试使用的SSID是简体中文,发现调用ICU库CharsetDetector类的detect函数。识别为Big5编码方式了,很明显这个是识别出错了,显示当然也是变成繁体的字符了,很明显这个返回错误是CharsetDetector识别不对导致的。
发现这个错误之后,不得不再次研究了GBK, GB2312, GB18030的编码以及台湾和香港、澳门采用的Big5繁体编码,发现两种编码都是区位吗,而且十六进制数值存在重叠,那当然可能会被识别错误,如何才可以精确识别呢?为啥ICU库也无法识别呢?答案其实就在ICU的设计上。
通过阅读icu库的源码,发现icu的字符编码识别有一套测评算法来针对待检测数据进行各种编码方式的评分,这个评分的变量就是confidence。待检测的数据在icu库按照其支持的所有编码方式挨个检测,每一种编码都有自己的记分值,经过理论的统计,如果不符合编码,其记分就是0,某个编码部分符合记分就会介于10-100之间,某个编码针对待检测数据的匹配度越高,记分值confidence也就是越高,当全部检测完成,把每个编码的计分值由大到小排列,记分值最大的字符编码就是待检测数据的编码方式,直接返回即可。
最后通过修改icu库中的Big5的字符编码检测方式,实现了对繁体和简体字符的精确判断。同时Android Frame的WiFi SSID调用ICU库的检测也获得了正确的SSID编码结果。
最终验证Android 7.1系统上,Android -> Setting -> WiFi 可以正确显示繁体和简体中文,连接中文也可以成功连接。
对比测试结果:苹果手机对繁体/简体中文SSID都是乱码,MTK手机也只是可以识别简体,繁体不支持。而且整个修改没有涉及到wpa_supplicant中间层的修改,而是在framework彻底解决了这个SSID的编码识别问题。
有需要完整修改细节的,请私信本人。
上述博客属原创,如要转载请著名出处。