Integrating the ZXing library directly into my Android application

后端 未结 17 1618
[愿得一人]
[愿得一人] 2020-11-22 04:35

I\'m writing this in mere desperation :) I\'ve been assigned to make a standalone barcode scanner (as a proof of concept) to an Android 1.6 phone.

For this i\'ve dis

17条回答
  •  春和景丽
    2020-11-22 05:16

    Here is a step-by-step guide on how to generate and display QR code using ZXing library without having to install the third-party application. Note: you don't have to build ZXing with ANT or any other build tool. The file core.jar is available in the released zip archive (read below).

    1. Download the latest release of ZXing. -- (ZXing-*.zip)
    2. Extract this zip archive and find core.jar under core/ directory.
    3. If you are using Eclipse IDE, drag and drop core.jar to the libs directory of your Android project. When asked, select Copy.
    4. Copy the two classes given below (Contents.java & QRCodeEncoder.java) to the main package of your Android project.
    5. Create an ImageView item in your Activity to display the generated QR code in if you don't have one already. An example is given below:
    6. Use the code snippet below to generate the QR code in Bitmap format and display it in an ImageView.

    Here is an ImageView element to add to your Activity layout XML file:

    
    

    Code snippet:

    // ImageView to display the QR code in.  This should be defined in 
    // your Activity's XML layout file
    ImageView imageView = (ImageView) findViewById(R.id.qrCode);
    
    String qrData = "Data I want to encode in QR code";
    int qrCodeDimention = 500;
    
    QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(qrData, null,
            Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), qrCodeDimention);
    
    try {
        Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
        imageView.setImageBitmap(bitmap);
    } catch (WriterException e) {
        e.printStackTrace();
    }
    

    Here is Contents.java

    //
    // * Copyright (C) 2008 ZXing authors
    // * 
    // * Licensed under the Apache License, Version 2.0 (the "License");
    // * you may not use this file except in compliance with the License.
    // * You may obtain a copy of the License at
    // * 
    // * http://www.apache.org/licenses/LICENSE-2.0
    // * 
    // * Unless required by applicable law or agreed to in writing, software
    // * distributed under the License is distributed on an "AS IS" BASIS,
    // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // * See the License for the specific language governing permissions and
    // * limitations under the License.
    // 
    
    import android.provider.ContactsContract;
    
    public final class Contents {
        private Contents() {
        }
    
        public static final class Type {
    
         // Plain text. Use Intent.putExtra(DATA, string). This can be used for URLs too, but string
         // must include "http://" or "https://".
            public static final String TEXT = "TEXT_TYPE";
    
            // An email type. Use Intent.putExtra(DATA, string) where string is the email address.
            public static final String EMAIL = "EMAIL_TYPE";
    
            // Use Intent.putExtra(DATA, string) where string is the phone number to call.
            public static final String PHONE = "PHONE_TYPE";
    
            // An SMS type. Use Intent.putExtra(DATA, string) where string is the number to SMS.
            public static final String SMS = "SMS_TYPE";
    
            public static final String CONTACT = "CONTACT_TYPE";
    
            public static final String LOCATION = "LOCATION_TYPE";
    
            private Type() {
            }
        }
    
        public static final String URL_KEY = "URL_KEY";
    
        public static final String NOTE_KEY = "NOTE_KEY";
    
        // When using Type.CONTACT, these arrays provide the keys for adding or retrieving multiple phone numbers and addresses.
        public static final String[] PHONE_KEYS = {
                ContactsContract.Intents.Insert.PHONE, ContactsContract.Intents.Insert.SECONDARY_PHONE,
                ContactsContract.Intents.Insert.TERTIARY_PHONE
        };
    
        public static final String[] PHONE_TYPE_KEYS = {
                ContactsContract.Intents.Insert.PHONE_TYPE,
                ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE,
                ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE
        };
    
        public static final String[] EMAIL_KEYS = {
                ContactsContract.Intents.Insert.EMAIL, ContactsContract.Intents.Insert.SECONDARY_EMAIL,
                ContactsContract.Intents.Insert.TERTIARY_EMAIL
        };
    
        public static final String[] EMAIL_TYPE_KEYS = {
                ContactsContract.Intents.Insert.EMAIL_TYPE,
                ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE,
                ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE
        };
    }
    

    And QRCodeEncoder.java

    /*
     * Copyright (C) 2008 ZXing authors
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    import android.provider.ContactsContract;
    import android.graphics.Bitmap;
    import android.os.Bundle;
    import android.telephony.PhoneNumberUtils;
    
    import java.util.Collection;
    import java.util.EnumMap;
    import java.util.HashSet;
    import java.util.Map;
    
    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.BitMatrix;
    
    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 uniquePhones = new HashSet(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 uniqueEmails = new HashSet(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;
    
            Map hints = null;
            String encoding = guessAppropriateEncoding(contents);
            if (encoding != null) {
                hints = new EnumMap(EncodeHintType.class);
                hints.put(EncodeHintType.CHARACTER_SET, encoding);
            }
            MultiFormatWriter writer = new MultiFormatWriter();
            BitMatrix 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++) {
                    pixels[offset + x] = result.get(x, y) ? BLACK : 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();
        }
    }
    

提交回复
热议问题