0

我正在尝试通过 Clickatell api 请求验证码并在我的活动中显示图像。我设法获得包含图像的 xml 响应,但我无法正确解码它以显示它(创建的位图始终为空)。

xml响应:

<ClICKATELLSDK>
<Action>get_captcha</Action>
<Result>Success</Result>
<Values>
<Value>
<captcha_id>c202a3fc98c50a5f8dccc8540077614e</captcha_id>
<captcha_image>%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%AF%00%00%00-%08%02%00%00%00W%88%AC%F1%00%00%12%1AIDATx%9C%ED%5CyxTU%B2%AFs%97%5E%93%EE%A4%B3%27%84l%24%21%40X%24%A8%04%81%A8++%22H%40% B8l%2C%E7%60%3D%14%27%831%D2%C5Z%E2Fu%08%3Cm3%A9%DB%EB%A2%2C% D2FsZ%83H%2B%7B%13s%0Du%87%D4%A6%F3DE%0E%5Db%7B.a%FFZ%D7T%1E% %06%94%96%89%F4%91%00%D0%9D2%85%1E%1B%FA%01%8A%AB+%E0%FF%00%CDSh%D94%F1%00%D8%00%00%00%00IEND%AEB%60%82
</captcha_image>
<Value>
</Values>
<Timestamp>1316511558</Timestamp>
</ClICKATELLSDK>

我解析这个 xml 并将验证码图像保存到一个字符串中,我在这段代码中使用它来创建位图:

captchaImage = <captcha_image from xml>
byte[] encodeByte = Base64.decode(captchaImage, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
4

2 回答 2

4

首先,我认为上面粘贴的 Url 编码值已损坏。在 url 编码中,十六进制表示必须在%字符之后。但是有这样的部分:%1E% %06

您可以使用此 TextUtil 类对字节数组进行编码/解码!

String xmlValue = <your xml captcha value>
byte[] decoded = TextUtil.urlDecode(xmlValue.getBytes("UTF-8"));

public final class TextUtil {
static final String HEX_DIGITS = "0123456789ABCDEF";

protected static String urlEncode(byte[] rs) {
    StringBuffer result = new StringBuffer(rs.length * 2);

    for (int i = 0; i < rs.length; i++) {
        char c = (char) rs[i];

        switch (c) {
        case '_':
        case '.':
        case '*':
        case '-':
        case '/':
            result.append(c);
            break;

        case ' ':
            result.append('+');
            break;

        default:
            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
                result.append(c);
            } else {
                result.append('%');
                result.append(HEX_DIGITS.charAt((c & 0xF0) >> 4));
                result.append(HEX_DIGITS.charAt(c & 0x0F));
            }
        }

    } 

    return result.toString();
}

protected static byte[] urlDecode(byte[] bytes) throws UnsupportedEncodingException,
        IllegalArgumentException {
    if (bytes == null) {
        return null;
    }

    byte[] decodeBytes = new byte[bytes.length];
    int decodedByteCount = 0;

    try {
        for (int count = 0; count < bytes.length; count++) {
            switch (bytes[count]) {
            case '+':
                decodeBytes[decodedByteCount++] = (byte) ' ';
                break;

            case '%':
                decodeBytes[decodedByteCount++] = (byte) ((HEX_DIGITS.indexOf(bytes[++count]) << 4) + (HEX_DIGITS
                        .indexOf(bytes[++count])));

                break;

            default:
                decodeBytes[decodedByteCount++] = bytes[count];
            }
        }

    } catch (IndexOutOfBoundsException ae) {
        throw new IllegalArgumentException("Malformed encoding");
    }

    return decodeBytes;
}
}
于 2012-12-06T00:47:13.630 回答
1

很多%表明您的图像是 Url 编码的。Base-64 只使用字母和数字。

Android 中的 url-decode 方法之一是Uri.decode(String)生成String. AString可以变成byte[]通孔String#getBytes()

所以以下可以工作

String captchaImage = <captcha_image from xml>;
String decodedString = Uri.decode(captchaImage);
byte[] decodedBytes = decodedString.getBytes("UTF-8");
Bitmap bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);

还有java.net.URLDecoder也可以让你指定字符集。

于 2012-12-05T23:54:51.857 回答