Zxing3.2.1 之前遇到过Android Zxing扫码乱码的问题,网上搜了下解决了下。 今天又遇到了问题。 依然会乱码。

研究总结如下:

Zxing 可以在Hints中添加默认编码格式。这个编码格式是用于解读Byte数据时,

1.如果码中没有指定编码集则,默认使用该编码格式。

2.如果制定了编码集,则使用编码指定的字符集。

并非强制,而中文的主要编码格式有两种,GBKUTF-8。

注意,网上有很多提到“ISO-8859-1”这个编码集的,这个编码集是个简单编码集,每个字节一个字符。并不是一个能表示中文的编码集。

有些情况可以利用他的单字节字符特性,进行字节和字符的互转。

但因为上面规则2的存在,使用这个编码集做byte取得的多多少少都有点问题。(如指明UTF-8编码的,则返回结果已经是utf8,用ISO8859取得bytes反儿会乱码,因为ISO无法表示UTF-8的字符,会替换为?号)。

因为,码生成不同,会包含是否指明编码格式两种情况,而编码本身又可能是Utf8或者GBK,而进行String转换的过程中,二进制信息会丢失。

因此思路上,如果可以取得原始的byte数组,就可以判断用正确的字符集显示了。应避免通过String转换取得。

解决也比较简单,看了下源码,发现其实扫码结果中本来就包含了这些信息。

//源码 QRCodeReader   public final Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)方法中
//向Result Metadata中放了一些额外信息。这是一个Map

……
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS,byteSegments);
……

这个result就是扫码结果result。 在实例中会在MipcaActivityCapture的扫码结果回调

public void handleDecode(Result result, Bitmap barcode)

byteSegments记录了原始二进制数据,直接判断二进制数据格式即可。注意判空,例如如果同时支持扫描条形码,是没有Metadata信息的。

                List<byte[]> byteSegments = (List<byte[]>) result.getResultMetadata().get(ResultMetadataType.BYTE_SEGMENTS);
StringBuffer buffer1 =new StringBuffer();
for (int i = 0; i < byteSegments.size(); i++) {
byte[] buffer =byteSegments.get(i);
String tempStr = "";
//猜一下编码格式
if(isUtf8(buffer)){
tempStr = new String(buffer, "utf-8");
}else{
tempStr = new String(buffer, "GBK");
} buffer1.append(tempStr);
}
resultString = buffer1.toString();

isUtf8 是网上抄来的一个工具函数,如下

    public static Boolean isUtf8(byte[] buffer) {
boolean isUtf8 = true;
int end = buffer.length;
for (int i = 0; i < end; i++) {
byte temp = buffer[i];
if ((temp & 0x80) == 0) {// 0xxxxxxx
continue;
} else if ((temp & 0xC0) == 0xC0 && (temp & 0x20) == 0) {// 110xxxxx 10xxxxxx
if (i + 1 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0) {
i = i + 1;
continue;
}
} else if ((temp & 0xE0) == 0xE0 && (temp & 0x10) == 0) {// 1110xxxx 10xxxxxx 10xxxxxx
if (i + 2 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0
&& (buffer[i + 2] & 0x80) == 0x80 && (buffer[i + 2] & 0x40) == 0) {
i = i + 2;
continue;
}
} else if ((temp & 0xF0) == 0xF0 && (temp & 0x08) == 0) {// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
if (i + 3 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0
&& (buffer[i + 2] & 0x80) == 0x80 && (buffer[i + 2] & 0x40) == 0
&& (buffer[i + 3] & 0x80) == 0x80 && (buffer[i + 3] & 0x40) == 0) {
i = i + 3;
continue;
}
}
isUtf8 = false;
break;
}
return isUtf8;
}

问题解决。

真·Android Zxing 扫码中文乱码解决的更多相关文章

  1. arcgis for android 读取shp文件中文乱码解决方法

    设置注册表默认字符,即可解决中文乱码问题. 'dbfDefault' 设置方法1.开始--运行,输入”Regedit“,打开注册表.2.如是用的是 10.x 版本 ArcGIS Desktop,定位到 ...

  2. Zxing中文乱码解决方法

    Zxing中文乱码解决方法总结 尝试过非常多方法  最后发现此方法解决的乱码最多....... 在百度搜索二维码图片 经过前2页的測试  除开一张图之外  其余都能扫描出结果 假设大家有更好的解决方法 ...

  3. zxing 扫码第三方SDK版本不兼容问题

    在AndroidStudio环境下,或许会遇到下面的问题: Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > ...

  4. java中文乱码解决之道(九)-----总结

    乱码,我们前台展示的杀手,可能有些朋友和我的经历一样:遇到乱码先按照自己的经验来解决,如果没有解决就google,运气好一搜就可以解决,运气不好可能够你折腾一番了.LZ之所以写这个系列博客就是因为遇到 ...

  5. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  6. php mysql 中文乱码解决方法

    本文章向码农们介绍php mysql 中文乱码解决方法,对码农们非常实用,需要的码农可以参考一下. 从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行 解 ...

  7. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

    原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)—–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...

  8. Java 前台后台数据传递、中文乱码解决方法

    1.向前台传递数据;2.向后台传递数据;3.ajax post 提交数据到服务端时中文乱码解决方法;4.数组类型参数传递; 1.向前台传递数据:1.1 字符串数据传递:  这种方式只是单一的向前台传递 ...

  9. Git Status 中文乱码解决

    现象: jb@H39:~/doc$ git statusOn branch masterYour branch is up-to-date with 'origin/master'. Untracke ...

  10. python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色)

    python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色) 前言 在 python 开发中,有时候想通过cmd窗口来和用户交互,比如显示信息之类的,会比自己创建 GUI 来的方便,但是随之而 ...

随机推荐

  1. Gzip之后继者Brotli浅析之CDN厂商的智能压缩,服务器Brotli设置

    "智能压缩"按照又拍云的说法是,同时支持 Gzip 和 Brotli 压缩算法.根据用于浏览器开启自动选择不同压缩方式. Gzip 压缩算法 Gzip 基于 DEFLATE 算法, ...

  2. 火山引擎 ByteHouse:TB 级数据下,如何实现高效、稳定的数据导入

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近期,火山引擎开发者社区.火山引擎数智平台(VeDI)联合举办以<数智化转型背景下的火山引擎大数据技术揭秘& ...

  3. 对话 BitSail Contributor | 梁奋杰:保持耐心,享受创造

    2022 年 10 月,字节跳动 BitSail 数据引擎正式开源.同期,社区推出 Contributor 激励计划第一期,目前已有 13 位外部开发者为 BitSail 社区做出贡献,成为了首批 B ...

  4. 第六届蓝桥杯(2015)C/C++大学A组省赛题解

    第一题.方程整数解 答案:10 18 24,最小的为 10 int main() { ios_base::sync_with_stdio(false), cin.tie(0); for (int i ...

  5. C# 防XSS攻击 示例

    思路: 对程序代码进行过滤非法的关键字 新建控制台程序,编写代码测试过滤效果 class Program { static void Main(string[] args) { //GetStrReg ...

  6. 使用docker compose 编排微服务发布

    本文为博主原创,未经允许不得转载: 目录: 1. compose 简介 2. compose 安装 3. 编写 docker-compose.yml 实现微服务发布 4. docker-compose ...

  7. centos7 systemctl配置开机自启动服务

    centos7使用systemctl替代原来/etc/init.d,按官方的说法是提高系统服务的运行效率.服务配置更加简单易用,对于一些自定义的服务来配置开机自启动,是真的香! 概念理解 它是服务管理 ...

  8. 非标准库--conio.h库

    1.getch函数 主要内容 int getch(void): 所在头文件:conio.h 函数用途:从控制台读取一个字符,但不显示在屏幕上,即一个不需要通过ENTER确定的getchar. 函数原型 ...

  9. Mybatis @Insert插入数据返回自增的主键id

    mapper层 @Insert("insert into t_user (username,password,valid,create_time) values (#{username},# ...

  10. javaweb 项目!号 解决方案

    1:右击项目工程名称2:Properties3:  Jvav Build Path4:  Libraries5:  Add External JARS6:  找到"E:\apache-tom ...