真·Android Zxing 扫码中文乱码解决
Zxing3.2.1 之前遇到过Android Zxing扫码乱码的问题,网上搜了下解决了下。 今天又遇到了问题。 依然会乱码。
研究总结如下:
Zxing 可以在Hints中添加默认编码格式。这个编码格式是用于解读Byte数据时,
1.如果码中没有指定编码集则,默认使用该编码格式。
2.如果制定了编码集,则使用编码指定的字符集。
并非强制,而中文的主要编码格式有两种,GBK和UTF-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 扫码中文乱码解决的更多相关文章
- arcgis for android 读取shp文件中文乱码解决方法
设置注册表默认字符,即可解决中文乱码问题. 'dbfDefault' 设置方法1.开始--运行,输入”Regedit“,打开注册表.2.如是用的是 10.x 版本 ArcGIS Desktop,定位到 ...
- Zxing中文乱码解决方法
Zxing中文乱码解决方法总结 尝试过非常多方法 最后发现此方法解决的乱码最多....... 在百度搜索二维码图片 经过前2页的測试 除开一张图之外 其余都能扫描出结果 假设大家有更好的解决方法 ...
- zxing 扫码第三方SDK版本不兼容问题
在AndroidStudio环境下,或许会遇到下面的问题: Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > ...
- java中文乱码解决之道(九)-----总结
乱码,我们前台展示的杀手,可能有些朋友和我的经历一样:遇到乱码先按照自己的经验来解决,如果没有解决就google,运气好一搜就可以解决,运气不好可能够你折腾一番了.LZ之所以写这个系列博客就是因为遇到 ...
- java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**
在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...
- php mysql 中文乱码解决方法
本文章向码农们介绍php mysql 中文乱码解决方法,对码农们非常实用,需要的码农可以参考一下. 从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行 解 ...
- java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**
原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)—–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...
- Java 前台后台数据传递、中文乱码解决方法
1.向前台传递数据;2.向后台传递数据;3.ajax post 提交数据到服务端时中文乱码解决方法;4.数组类型参数传递; 1.向前台传递数据:1.1 字符串数据传递: 这种方式只是单一的向前台传递 ...
- Git Status 中文乱码解决
现象: jb@H39:~/doc$ git statusOn branch masterYour branch is up-to-date with 'origin/master'. Untracke ...
- python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色)
python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色) 前言 在 python 开发中,有时候想通过cmd窗口来和用户交互,比如显示信息之类的,会比自己创建 GUI 来的方便,但是随之而 ...
随机推荐
- Vue 应用程序性能优化:代码压缩、加密和混淆配置详解
简介在 Vue 应用程序的开发中,代码压缩.加密和混淆是优化应用程序性能和提高安全性的重要步骤. Vue CLI 是一个功能强大的开发工具,它提供了方便的配置选项来实现这些功能.本文将介绍如何使用 ...
- Solon cloud 使用融断器 sentinel 或 guava 或 semaphore
Solon Cloud 是一套防腐层的架构方案.提供统一的接口定义和配置设计,从而实现不同框架统一体验的效果. 目前,已适配的融断器有三个插件且体验方式完全相同,分别是: sentinel-solon ...
- Linux 创建新用户
添加用户组[root@VipSoft ~]#groupadd admin 添加用户[root@VipSoft ~]#useradd jimmy -m -d /home/jimmy -g admin 修 ...
- 【Docker】docker介绍 什么是虚拟化 容器与虚拟机比较 Docker 概念 docker安装
目录 docker介绍 什么是虚拟化 docker是什么 容器与虚拟机比较 Docker 概念 docker安装 docker介绍 什么是虚拟化 在计算机中,虚拟化(英语:Virtualization ...
- Mysql--between
between 用于where 表达式中,选取介于两个值之间的数据范围,同and一起搭配使用 语法: expr [NOT] BETWEEN begin_expr AND end_expr; 在整个表达 ...
- AtCoder Beginner Contest 166 (A~E)
比赛链接:Here AB水题 C - Peaks 题意: 给出 \(n\) 个观察台的高度,以及 \(m\) 条边,定义"好观察台":比所有直接相连的观测台都高 思路: 因为道路是 ...
- POJ2965 The Pilots Brothers' refrigerator (精妙方法秒杀DFS BFS)
这道题和算法进阶指南的一道题解法一样,必须另操作为奇数.见证明过程 证明:要使一个为'+'的符号变为'-',必须其相应的行和列的操作数为奇数;可以证明,如果'+'位置对应的行和列上每一个位置都进行一次 ...
- vivo 商城前端架构升级—前后端分离篇
本文主要以 vivo 商城项目的前后端分离经验,总结前后端分离思路,整理前后端分离方案,以及分离过程中遇到的问题及解决方案. 一.前言 vivo官方商城在2015年创建网上商城,开辟网络销售渠道,几年 ...
- 如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件
某讯的手游保护系统用的都是一套,在其官宣的手游加固功能中有一项宣传是对比较热门的Unity3d引擎的手游保护方案,其中对Dll文件的保护介绍如下, "Dll加固混淆针对Unity游戏,对 ...
- 14-Verilog for Verification
Verilog for Verification 1.引言 Testbench也是一个模块(module...endmodule) Testbench没有输入和输出,因为它是一个闭环,自己产生激励,灌 ...