9

我正在开发一个 Android 应用程序,我需要在使用 ZXing 应用程序生成的 QRCode 中对字节数组进行编码和解码。我的问题是我解码的消息与生成的字节数组不完全匹配。我试图创建一个基于包含递增索引的字节数组的二维码,即

input = [0, 1, 2, ..., 124, 125, 126, 127, -128, -127,... -3, -2, -1, 0, 1, 2, ...]

在 QRCode 中对消息进行编码并在响应端对其进行解码后,我得到以下字节数组输出:

output = [0, 1, 2, ..., 124, 125, 126, 127, 63, 63,... 63, 63, 63, 0, 1, 2, ...]

所有“负”字节值都转换为 ASCII char 63: '?' 问号字符。我认为编码字符集出了点问题,但由于我使用的是 ISO-8859-1,每个人都声称它是此类问题的解决方案(其他主题处理相同类型的问题此处),我不看不出我的错误在哪里,或者我是否在编码或解码的实例化过程中跳过了一个步骤。这是我执行以对给定字节数组进行编码的代码:

String text = "";
byte[] res = new byte[272];
for (int i = 0; i < res.length; i++) {
    res[i] = (byte) (i%256);
}
try {
    text = new String(res, "ISO8859_1");
} catch (UnsupportedEncodingException e) {
    // TODO
}
Intent intent = new Intent(Intents.Encode.ACTION);
Intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
intent.putExtra(Intents.Encode.FORMAT, "ISO8859_1");
intent.putExtra(Intents.Encode.DATA, text);
intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());

boolean useVCard = intent.getBooleanExtra(USE_VCARD_KEY, false);
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(activity, intent, dimension, useVCard);
Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();

为了解码 QRCode,我发送以下 Intent

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.qrcodeDecoding);

    Intent intent = new Intent(Intents.Scan.ACTION);
    intent.putExtra(Intents.Scan.MODE, Intents.Scan.QR_CODE_MODE);
    startActivityForResult(intent, 0);
}

并等待结果:

@Override
protected void onActivityResult(int request, int result, Intent data)
{
    if(request == 0)
    {
        //action
        if(result == RESULT_OK)
        {
            String res = data.getStringExtra(Intents.Scan.RESULT);
            byte[] dat = null;

            try{
                    dat = res.getBytes("ISO8859_1");
            } catch(UnsopportedEncodingException e) {
                    //TODO
            }
        }
        else if(result == RESULT_CANCELED)
        {
            //TODO
        }
    }

}

你能告诉我我的错误在哪里,或者我应该在哪里看?

十分感谢,

弗兰克

4

3 回答 3

5

在我的一个应用程序中,我需要对使用 ZXing 应用程序生成的 QRCode 中的字节数组进行编码和解码。由于字节数组包含压缩文本数据,我想避免使用 base64 编码。可以这样做,但由于我到目前为止还没有看到完整的代码片段集,所以我将它们发布在这里。

编码:

public void showQRCode(Activity activity, byte[] data){
  Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
  intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
  intent.putExtra("ENCODE_SHOW_CONTENTS", false);
  intent.putExtra("ENCODE_DATA", new String(data, "ISO-8859-1"));
  activity.startActivity(intent);
}

开始扫描:

public static void startQRCodeScan(Activity activity){
  Intent intent = new Intent(com.google.zxing.client.android.SCAN);
  intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
  intent.putExtra("CHARACTER_SET", "ISO-8859-1");
  activity.startActivityForResult(intent, 0);
}

扫描结果处理程序:

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
  byte[] result = intent.getStringExtra("SCAN_RESULT").getBytes("ISO-8859-1");
  ...
}

我认为在开始扫描的意图数据中没有将 CHARACTER_SET 设置为 ISO-8859-1 是导致原始问题代码失败的原因。我花了很长时间才弄清楚这个问题,因为我在任何地方都没有看到这个清晰的帖子,而且拉丁 1 编码是 Xzing 中 QR 码的标准编码。尤其棘手的是,Xzing 在线解码器http://zxing.org/w/decode.jspx也没有设置 CHARACTER_SET,因此在此站点上解码时生成的 QR 码看起来有问题。

于 2013-10-22T20:28:56.043 回答
2

您错误地认为可以将任意二进制数据转换为有效字符串,而无需使用某种装甲。它不起作用。Binary -> text -> binary 使用任何标准字符集/编码都是有损的。(提示:使用 UTF-8 也不起作用。)

您应该使用 base64 编码或十六进制编码之类的东西来确保二进制数据不会被破坏。

于 2012-06-17T01:54:59.970 回答
1

从概念上讲,二维码编码的是文本,而不是字节。当然,它们在内部将输入转换为一系列字节,尽管这对调用者来说是不透明的。你是对的,碰巧选择正确的编码会让你偷偷通过,ISO-8859-1 是正确的选择。实际上,它确实有效。

ASCII 是不可能的,因为它没有为 >= 128 定义字符,而且 UTF-8 绝对行不通

这里的问题可能是您的代码。我不确定你在这里尝试什么......看起来你正在设置发送某个Intent地方(到条形码扫描仪?)但是你没有,你只是在制作一个Intent并将它发送到一些代码你从项目中复制?我想你如何为Intent.

如果您在应用程序中执行此操作,这应该会简单得多。只需QRCodeEncoder.encodeAsBitmap()直接重用并删除其余部分。

于 2012-06-17T10:26:18.900 回答