如何构建扫描QR码并在Android上使用其数据的应用?

时间:2016-01-06 11:02:33

标签: android qr-code barcode-scanner

请注意,我是Android开发的新手,并且只取得了“Hello world”的进展。

我实际上并不想构建二维码扫描器,我宁愿使用第三方组件,但我需要一个应用程序来扫描二维码,从代码中显示一些数据,并将一些数据发送到网络服务。

请有人给我一个关于U应该在我的应用程序中使用的过程和结构的真正的初学者大纲。我是一位经验丰富的C#开发人员,因此实际的Java编码不会成为问题,我当然不会问如何做到这一点,只是如何设置基本的应用程序架构和流程,例如如何显示对话,联系Web服务以及使用第三方组件。

我需要的是扫描QR码,从中提取一些文本代码,将这些代码发送到网络服务。

3 个答案:

答案 0 :(得分:1)

ZXing是一个非常好的库,您可以将其集成到您的应用程序中。请参阅此课程CaptureActivity

答案 1 :(得分:1)

首先您需要zxing library来创建QR码,并且需要一个已安装的应用程序来读取BarcodeScanner等QR码和类似的编码器类:

import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.telephony.PhoneNumberUtils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.ByteMatrix;

public final class QRCodeEncoder {
    private static final int WHITE = 0xFFFFFFFF;
    private static final int BLACK = 0xFF000000;

private int dimension = Integer.MIN_VALUE;
private String contents = null;
private String displayContents = null;
private String title = null;
private BarcodeFormat format = null;
private boolean encoded = false;

public QRCodeEncoder(String data, Bundle bundle, String type, String format, int dimension) {
    this.dimension = dimension;
    encoded = encodeContents(data, bundle, type, format);
}

public String getContents() {
    return contents;
}

public String getDisplayContents() {
    return displayContents;
}

public String getTitle() {
    return title;
}

private boolean encodeContents(String data, Bundle bundle, String type, String formatString) {
    // Default to QR_CODE if no format given.
    format = null;
    if (formatString != null) {
        try {
            format = BarcodeFormat.valueOf(formatString);
        } catch (IllegalArgumentException iae) {
            // Ignore it then
        }
    }
    if (format == null || format == BarcodeFormat.QR_CODE) {
        this.format = BarcodeFormat.QR_CODE;
        encodeQRCodeContents(data, bundle, type);
    } else if (data != null && data.length() > 0) {
        contents = data;
        displayContents = data;
        title = "Text";
    }
    return contents != null && contents.length() > 0;
}

private void encodeQRCodeContents(String data, Bundle bundle, String type) {
    if (type.equals(Contents.Type.TEXT)) {
        if (data != null && data.length() > 0) {
            contents = data;
            displayContents = data;
            title = "Text";
        }
    } else if (type.equals(Contents.Type.EMAIL)) {
        data = trim(data);
        if (data != null) {
            contents = "mailto:" + data;
            displayContents = data;
            title = "E-Mail";
        }
    } else if (type.equals(Contents.Type.PHONE)) {
        data = trim(data);
        if (data != null) {
            contents = "tel:" + data;
            displayContents = PhoneNumberUtils.formatNumber(data);
            title = "Phone";
        }
    } else if (type.equals(Contents.Type.SMS)) {
        data = trim(data);
        if (data != null) {
            contents = "sms:" + data;
            displayContents = PhoneNumberUtils.formatNumber(data);
            title = "SMS";
        }
    } else if (type.equals(Contents.Type.CONTACT)) {
        if (bundle != null) {
            StringBuilder newContents = new StringBuilder(100);
            StringBuilder newDisplayContents = new StringBuilder(100);

            newContents.append("MECARD:");

            String name = trim(bundle.getString(ContactsContract.Intents.Insert.NAME));
            if (name != null) {
                newContents.append("N:").append(escapeMECARD(name)).append(';');
                newDisplayContents.append(name);
            }

            String address = trim(bundle.getString(ContactsContract.Intents.Insert.POSTAL));
            if (address != null) {
                newContents.append("ADR:").append(escapeMECARD(address)).append(';');
                newDisplayContents.append('\n').append(address);
            }

            Collection<String> uniquePhones = new HashSet<String>(Contents.PHONE_KEYS.length);
            for (int x = 0; x < Contents.PHONE_KEYS.length; x++) {
                String phone = trim(bundle.getString(Contents.PHONE_KEYS[x]));
                if (phone != null) {
                    uniquePhones.add(phone);
                }
            }
            for (String phone : uniquePhones) {
                newContents.append("TEL:").append(escapeMECARD(phone)).append(';');
                newDisplayContents.append('\n').append(PhoneNumberUtils.formatNumber(phone));
            }

            Collection<String> uniqueEmails = new HashSet<String>(Contents.EMAIL_KEYS.length);
            for (int x = 0; x < Contents.EMAIL_KEYS.length; x++) {
                String email = trim(bundle.getString(Contents.EMAIL_KEYS[x]));
                if (email != null) {
                    uniqueEmails.add(email);
                }
            }
            for (String email : uniqueEmails) {
                newContents.append("EMAIL:").append(escapeMECARD(email)).append(';');
                newDisplayContents.append('\n').append(email);
            }

            String url = trim(bundle.getString(Contents.URL_KEY));
            if (url != null) {
                // escapeMECARD(url) -> wrong escape e.g. http\://zxing.google.com
                newContents.append("URL:").append(url).append(';');
                newDisplayContents.append('\n').append(url);
            }

            String note = trim(bundle.getString(Contents.NOTE_KEY));
            if (note != null) {
                newContents.append("NOTE:").append(escapeMECARD(note)).append(';');
                newDisplayContents.append('\n').append(note);
            }

            // Make sure we've encoded at least one field.
            if (newDisplayContents.length() > 0) {
                newContents.append(';');
                contents = newContents.toString();
                displayContents = newDisplayContents.toString();
                title = "Contact";
            } else {
                contents = null;
                displayContents = null;
            }

        }
    } else if (type.equals(Contents.Type.LOCATION)) {
        if (bundle != null) {
            // These must use Bundle.getFloat(), not getDouble(), it's part of the API.
            float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
            float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
            if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
                contents = "geo:" + latitude + ',' + longitude;
                displayContents = latitude + "," + longitude;
                title = "Location";
            }
        }
    }
}

public Bitmap encodeAsBitmap() throws WriterException {
    if (!encoded) return null;

    Hashtable hints = null;
    String encoding = guessAppropriateEncoding(contents);
    if (encoding != null) {
    hints = new Hashtable();
    hints.put(EncodeHintType.CHARACTER_SET, encoding);
    }
    MultiFormatWriter writer = new MultiFormatWriter();
    ByteMatrix result =writer.encode(contents, format, dimension, dimension, hints);
    int width = result.getWidth();
    int height =result.getHeight();
    int[] pixels = new int[width * height];
    // All are 0, or black, by default
    for (int y = 0; y < height; y++) {
    int offset = y * width;
    for (int x = 0; x < width; x++) {

    if(result.get(x, y)== 0)
    {
    pixels[offset + x] = BLACK ;
    }
    else
    pixels[offset + x] = WHITE ;

    }
    }

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return bitmap;
    }

private static String guessAppropriateEncoding(CharSequence contents) {
    // Very crude at the moment
    for (int i = 0; i < contents.length(); i++) {
        if (contents.charAt(i) > 0xFF) { return "UTF-8"; }
    }
    return null;
}

private static String trim(String s) {
    if (s == null) { return null; }
    String result = s.trim();
    return result.length() == 0 ? null : result;
}

private static String escapeMECARD(String input) {
    if (input == null || (input.indexOf(':') < 0 && input.indexOf(';') < 0)) { return input; }
    int length = input.length();
    StringBuilder result = new StringBuilder(length);
    for (int i = 0; i < length; i++) {
        char c = input.charAt(i);
        if (c == ':' || c == ';') {
            result.append('\\');
        }
        result.append(c);
    }
    return result.toString();
}
}

希望这能帮助你:)

答案 2 :(得分:0)

你也可以考虑使用非常快速,经济有效的manateework sdk。我有适用于支持不同平台的移动应用程序的SDK。 iOS,Android等和代码符号系统。 PL。有关此sdk的详细信息,请参阅https://manateeworks.com/