การรวมไลบรารี ZXing เข้ากับแอปพลิเคชัน Android ของฉันโดยตรง


141

ฉันกำลังเขียนสิ่งนี้ด้วยความสิ้นหวัง :) ฉันได้รับมอบหมายให้ทำเครื่องสแกนบาร์โค้ดแบบสแตนด์อโลน (เพื่อพิสูจน์แนวคิด) ไปยังโทรศัพท์ Android 1.6

สำหรับสิ่งนี้ฉันได้ค้นพบห้องสมุด ZXing แล้ว

ฉันได้อ่านอ่านหัวข้อที่เกี่ยวข้องที่นี่ใน StackOverflow ใช้สามัญสำนึกและอื่น ๆ ดูเหมือนจะไม่มีอะไรช่วยได้และฉันก็ไม่สามารถเจาะรูบนด่านนี้ได้: /

ฉันรู้ว่ามันเป็นไปได้ที่จะใช้ lib และสร้างเครื่องสแกนบาร์โค้ดแบบสแตนด์อโลนของคุณเอง ฉันได้อ่านแล้วว่าการใช้ "เครื่องสแกนบาร์โค้ด" ที่จัดทำโดย Zxing folks นั้นเป็นวิธีที่ง่ายที่สุด (ผ่านทางเจตนา) น่าเสียดายที่นี่ไม่ใช่ตัวเลือกและต้องการแอปแบบสแตนด์อโลน

ดังนั้นเพื่อสรุปปัญหาของฉัน:

  1. จะรวมแหล่ง ZXing lib เข้ากับโครงการ Android Code ของฉันผ่าน Eclipse ได้อย่างไร
  2. เมื่อรวม ... วิธีการใช้ lib, เพื่อ "โหลด" ฟังก์ชั่นการสแกน?
  3. คู่มือแบบขั้นตอนเป็นที่ต้องการมากกว่าเพราะฉันเพิ่งเริ่มทำงานใน Eclipse

ฉันพยายามทำให้โค้ดของฉันขึ้นอยู่กับโฟลเดอร์ Android จากโฟลเดอร์ ZXing source เมื่อฉันทำเช่นนั้นมีข้อผิดพลาดเกิดขึ้นที่ handfull ส่วนใหญ่เกี่ยวกับ 'org.apache' (??)

ฉันแค่คิดออกไม่ออก ... ดังนั้นคำใบ้สองสามข้อก็จะเป็นประโยชน์ที่สุด

ล่วงหน้าขอบคุณ :)


ฉันเชื่อว่าสิ่งที่คุณต้องการทำอยู่ที่นี่: stackoverflow.com/questions/4854442/…
Danny Remington - OMS

ZXing ไม่ใช่วิธีเดียวในการอ่านบาร์โค้ด ในฐานะของปี 2016 มันง่ายมากที่จะใช้API Android บาร์โค้ด
Dan Dascalescu

คำตอบ:


127

UPDATE! - แก้ไขแล้ว + แนวทาง

ฉันสามารถหาคำตอบได้ :) และด้านล่างคุณสามารถอ่านคำแนะนำทีละขั้นเพื่อหวังว่าจะสามารถช่วยเหลือผู้อื่นด้วยปัญหาเดียวกับที่ฉันมี;)

  1. ติดตั้ง Apache Ant - ( ดูวิดีโอ YouTube นี้เพื่อขอความช่วยเหลือ config )
  2. ดาวน์โหลด ZXing source จากหน้าแรกของ ZXing และแตกไฟล์
  3. ด้วยการใช้ของ Windows commandline นี้ (Run-> CMD) zxing srcนำทางไปยังไดเรกทอรีรากของที่ดาวน์โหลดมา
  4. ใน commandline หน้าต่าง - ประเภทant -f core/build.xmlกดและปล่อยให้ Apache ทำงานของมันวิเศษ [ มีปัญหา? ]
  5. ป้อน Eclipse -> โครงการ Android ใหม่โดยยึดตามโฟลเดอร์ android ในไดเรกทอรีที่คุณเพิ่งแตกออกมา
  6. คลิกขวาที่โฟลเดอร์โครงการ -> Properties -> Java Build Path -> Library -> เพิ่ม JAR ภายนอก ...
  7. นำทางไปยังโฟลเดอร์ที่แตกใหม่และเปิดไดเรกทอรีหลักและเลือกcore.jar... กด Enter!

ตอนนี้คุณเพียงแค่ต้องแก้ไขข้อผิดพลาดเล็กน้อยในการแปลและไฟล์ AndroidManifest.xml :) ตอนนี้คุณสามารถรวบรวมได้อย่างมีความสุขและตอนนี้คุณจะมีแอปสแกนบาร์โค้ดแบบสแตนด์อโลนที่ทำงานได้ตามแหล่ง ZXing;)

พวกโค้ดที่มีความสุข - ฉันหวังว่ามันจะช่วยคนอื่น :)


เขียนดีมาก! คุณสามารถเพิ่มรายละเอียดเกี่ยวกับสิ่งที่คุณแก้ไขในAndroidManifest.xmlไฟล์ได้หรือไม่? ฉันไม่เห็นข้อผิดพลาดใด ๆ ในไฟล์นั้นเมื่อทำการตรวจสอบ ขอบคุณ!
Brian Armstrong

7
ไม่มีข้อผิดพลาดในไฟล์ AndroidManifest.xml หรือการแปล อย่างไรก็ตามมีปัญหาความเข้ากันได้ใน Android SDK ล่าสุด ถ้าคุณใช้คุณต้องใช้ซอร์สโค้ดในภายหลังจาก SVN
Sean Owen

สวัสดีฉันพยายามพัฒนาแอปพลิเคชั่นอื่นสำหรับการสแกน QR เป็นแอปเดี่ยวโดยไม่ต้องใช้แอพ QR Droid หรือบาร์โค้ดสแกนเนอร์ มีขั้นตอนที่คุณกล่าวถึงในการทำเช่นนั้นหรือคุณยังใช้แอพอื่นผ่านทาง Intents หรืออะไรบ้าง?
Kumar

1
แพ็คเกจ zip จากcode.google.com/p/zxing/downloads/listมีไดเรกทอรี "คอร์" รวมถึง "android" และ "android-integration" อะไรคือเหตุผลที่คุณใช้ "แก่น"?
Michał K

1
เอาล่ะตอนนี้ฉันรู้แล้วว่าทำไม หากใครสงสัยเช่นกันโปรดดูstackoverflow.com/questions/4854442/…
Michał K

83

นี่คือคำแนะนำทีละขั้นตอนเกี่ยวกับวิธีการสร้างและแสดงรหัส QR โดยใช้ห้องสมุด ZXing โดยไม่ต้องติดตั้งแอปพลิเคชันของบุคคลที่สาม หมายเหตุ:คุณไม่จำเป็นต้องสร้าง ZXing ด้วย ANT หรือเครื่องมือสร้างอื่น ๆ ไฟล์core.jarนี้มีอยู่ในไฟล์ zip ที่เปิดตัว (อ่านด้านล่าง)

  1. ดาวน์โหลดรุ่นล่าสุดของ ZXing - ( ZXing-*.zip)
  2. แยกไฟล์ zip นี้และค้นหาcore.jarภายใต้core/ไดเรกทอรี
  3. หากคุณกำลังใช้ Eclipse IDE ให้ลากและวางcore.jarไปยังlibsไดเรกทอรีของโครงการ Android ของคุณ เมื่อถามว่าเลือกCopy
  4. คัดลอกสองคลาสที่ระบุด้านล่าง ( Contents.java& QRCodeEncoder.java) ไปยังแพ็คเกจหลักของโครงการ Android ของคุณ
  5. สร้างImageViewรายการในกิจกรรมของคุณเพื่อแสดงรหัส QR ที่สร้างขึ้นหากคุณยังไม่มี ตัวอย่างได้รับด้านล่าง:
  6. ใช้ข้อมูลโค้ดด้านล่างเพื่อสร้างรหัส QR ในรูปแบบ Bitmap ImageViewและแสดงไว้ใน

นี่คือImageViewองค์ประกอบที่จะเพิ่มลงในไฟล์ XML โครงร่างกิจกรรมของคุณ:

<ImageView 
    android:id="@+id/qrCode"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="50dp"
    android:layout_centerHorizontal="true"/>

ข้อมูลโค้ด:

// 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();
}

ที่นี่คือ 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
    };
}

และ 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<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;

        Map<EncodeHintType, Object> hints = null;
        String encoding = guessAppropriateEncoding(contents);
        if (encoding != null) {
            hints = new EnumMap<EncodeHintType, Object>(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();
    }
}

13
ZXing ล่าสุดไม่ได้มี core.jar มีเหตุผลบางอย่าง ฉันต้องดาวน์โหลด 2.1 สำหรับมัน
capcom

12
core.jar มีให้บริการแยกต่างหากในที่เก็บ Maven release สำหรับรุ่น 2.2 ลิงก์คือrepo1.maven.org/maven2/com/google/zxing/core/2.2/core-2.2.jar
Nantoka

12
Zxing 2.3.0 core.jar ที่นี่: repo1.maven.org/maven2/com/google/zxing/core/2.3.0
Rui Marques

1
encodeAsBitmap ของคุณ () วิธีการคืนค่าเป็นโมฆะถ้าไม่แก้ไขหรือล้มเหลวด้วย NullPointerException ถ้าฉันแสดงความคิดเห็นออกบรรทัดที่ส่งกลับเป็นโมฆะ ฉันใหม่กับห้องสมุดนี้ ผมทำอะไรผิดหรือเปล่า?
KG6ZVP

2
@Wesam มันมีประโยชน์จริงๆ แต่คุณสามารถให้รหัสได้หรือไม่ซึ่งสามารถย้อนกลับได้ ฉันหมายความว่าแปลงรหัส QR กลับไปเป็นสตริงหรือไม่
Shaon Hasan

15

compile 'com.google.zxing:core:2.3.0'

น่าเสียดายที่ไม่ได้ผลสำหรับฉัน

นี่คือสิ่งที่ได้ผลสำหรับฉัน:

dependencies {
   compile 'com.journeyapps:zxing-android-embedded:3.0.1@aar'
   compile 'com.google.zxing:core:3.2.0'
}

กรุณาหาลิงค์ที่นี่: https://github.com/journeyapps/zxing-android-embedded


1
คำตอบนี้แคระโดยคำตอบอื่น ๆ ที่นี่ ส่วนใหญ่มีภาพหน้าจอและเช่น นั่นเป็นความอัปยศเพราะนี่เป็นคำตอบเดียวที่ใช้งานได้จริง! เอาใจใส่กับสิ่งนี้ สิ่งที่เขาไม่ได้กล่าวถึงคือโครงการที่เชื่อมโยงเป็นสาขาที่มีคนสร้างห้องสมุดที่ยากลำบากนี้ให้กลายเป็นเรื่องง่าย เพียงดาวน์โหลด jar หลักจากโครงการ ZXING ปกติแล้วคุณก็พร้อมที่จะไป แม้มีตัวอย่าง !!!!
StarWind0

1
ฉันหวังว่าฉันจะสามารถให้คะแนนมากขึ้น คุณไม่รู้ว่ากี่ครั้งที่ฉันพยายามคิดโครงการต่าง ๆ ในช่วงหลายปีที่ผ่านมา
StarWind0

1
ฉันมีความสุขที่จะให้บริการคน :)
Karoly

11

มีปัญหาในการสร้างด้วย ANT หรือไม่ อ่านต่อไป

ถ้าant -f core/build.xml บอกว่าชอบ:

Unable to locate tools.jar. Expected to find it in
C:\Program Files\Java\jre6\lib\tools.jar

จากนั้นตั้งค่าJAVA_HOMEตัวแปรสภาพแวดล้อมของคุณเป็นโฟลเดอร์ java ที่เหมาะสม ฉันพบ tools.jar ในของฉัน (สำหรับ Windows):

C:\Program Files\Java\jdk1.6.0_21\lib

ดังนั้นฉันตั้งของฉันJAVA_HOMEเป็น:

C:\Progra~1\Java\jdk1.6.0_25

เหตุผลที่ฉันพบซินแทกซ์สั้นกว่าในเว็บไซต์บางแห่งที่ระบุว่า:

"ขอแนะนำอย่างยิ่งให้คุณเลือกไดเรกทอรีการติดตั้งที่ไม่รวมช่องว่างในชื่อพา ธ (เช่นห้ามติดตั้งในไฟล์ C: \ Program) หากติดตั้ง Java ในไดเรกทอรีดังกล่าวสิ่งสำคัญคือต้องตั้งค่า JAVA_HOME ตัวแปรสภาพแวดล้อมไปยังพา ธ ที่ไม่มีช่องว่าง (เช่น C: \ Progra ~ 1) ความล้มเหลวในการทำเช่นนี้จะส่งผลให้เกิดข้อยกเว้นที่โปรแกรมบางโปรแกรมขึ้นอยู่กับค่าของ JAVA_HOME "

จากนั้นฉันจะเปิดใช้งาน cmd ใหม่ (สำคัญเนื่องจากเชลล์ DOS อ่าน env vars เมื่อเปิดตัวเท่านั้นดังนั้นการเปลี่ยน env var จะทำให้คุณต้องใช้เชลล์ใหม่เพื่อรับค่าที่อัปเดต)

และในที่สุดก็ant -f core/build.xmlทำงาน


11

เนื่องจากคำตอบบางคำล้าสมัยฉันต้องการให้คำตอบของตัวเอง -

ในการรวมไลบรารี ZXing เข้ากับแอพ Android ของคุณตามที่Wiki แนะนำไว้คุณต้องเพิ่มไฟล์ Java 2 ไฟล์ลงในโครงการของคุณ:

จากนั้นในAndroid Studio ให้เพิ่มบรรทัดต่อไปนี้ในไฟล์build.gradle :

dependencies {
    ....
    compile 'com.google.zxing:core:3.2.1'
}

หรือถ้ายังคงใช้Eclipse กับ ADT-pluginเพิ่มไฟล์core.jarไปยังไดเรกทอรีย่อยlibsของโครงการของคุณ (ที่นี่Windows เต็มหน้าจอและMac แบบเต็มหน้าจอ ):

ภาพหน้าจอของ Windows

ในที่สุดเพิ่มรหัสนี้ในMainActivity.javaของคุณ:

public void scanQRCode(View v) {
    IntentIntegrator integrator = new IntentIntegrator(MainActivity.this);
    integrator.initiateScan(IntentIntegrator.QR_CODE_TYPES);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    IntentResult result = 
        IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
    if (result != null) {
        String contents = result.getContents();
        if (contents != null) {
            showDialog(R.string.result_succeeded, result.toString());
        } else {
            showDialog(R.string.result_failed,
                getString(R.string.result_failed_why));
        }
    }
}

private void showDialog(int title, CharSequence message) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton(R.string.ok_button, null);
    builder.show();
}

แอพที่เป็นผลลัพธ์จะขอให้ติดตั้งและเริ่มต้นแอปเครื่องสแกนบาร์โค้ดโดย ZXing (ซึ่งจะกลับไปที่แอพของคุณโดยอัตโนมัติหลังจากการสแกน):

แอปเครื่องสแกนบาร์โค้ด

นอกจากนี้หากคุณต้องการสร้างและเรียกใช้แอปทดสอบ ZXingเป็นแรงบันดาลใจสำหรับแอปของคุณเอง:

แอปทดสอบ ZXing

จากนั้นคุณต้องมีไฟล์ Java 4 ไฟล์จากGitHub :

  • BenchmarkActivity.java
  • BenchmarkAsyncTask.java
  • BenchmarkItem.java
  • ZXingTestActivity.java

และ 3 ไฟล์ Jar จากที่เก็บ Maven :

  • core.jar
  • หุ่นยนต์ core.jar
  • หุ่นยนต์ integration.jar

(คุณสามารถสร้างไฟล์ Jar ด้วยตัวคุณเองmvn package- ถ้าคุณเช็คเอาท์ ZXing จาก GitHub และติดตั้งเครื่องมือantและmavenที่คอมพิวเตอร์ของคุณ)

หมายเหตุ: หากโครงการของคุณไม่รู้จักไฟล์ Jar คุณอาจต้องอัปเดตเวอร์ชั่น Java ในคุณสมบัติโครงการ:

ภาพหน้าจอของคุณสมบัติ


2
นั่นเป็นคำตอบที่ยอดเยี่ยม!
Paresh Mayani

3
ฉันกลัวว่านี่จะพลาดจุดของคำถาม :-( ประเด็นก็คือไม่ต้องพึ่งพาแอปพลิเคชันภายนอกซึ่งแสดงวิธีการ .. ใช้แอปพลิเคชันภายนอกใช่หรือไม่ดูในชื่อคำถาม "โดยตรงใน"
StarWind0

5

ใส่

compile 'com.google.zxing:core:2.3.0' 

เป็นการอ้างอิง Gradle ของคุณ เป็นเรื่องง่ายเหมือนที่ ก่อนที่จะใช้ระบบ Android Studio และ Gradle build


ขวา! นั่นเป็นทางออกที่แท้จริงในปี 2558 Btw รุ่นปัจจุบันคือ 3.2.0
funcoder

สิ่งนี้ใช้ได้กับทุกคนหรือไม่ IntentIntegrator ยังคงไม่พบ
Karoly

คุณควรคัดลอกไฟล์ IntentIntegrator.javaและ IntentResult.javaด้วยตนเองลงในโครงการ Android Studio ของคุณ
Alexander Farber

4

คุณเคยเห็นหน้า wikiบนเว็บไซต์ zxing หรือไม่ ดูเหมือนว่าคุณอาจพบว่าการเริ่มต้นใช้งานDeveloperNotesและScanningViaIntent มีประโยชน์


ขออภัย ... มันไม่ได้เป็นตัวช่วยที่ฉันกำลังมองหา :) แต่วันนี้ฉันมีความก้าวหน้า: PI สามารถหาคำตอบได้ด้วยตัวเอง;) คำแนะนำสำหรับผู้ชมคนอื่น ๆ ที่มีปัญหาเดียวกันจะถูกโพสต์อย่างถูกต้อง :)
AppDev

2

หากคุณต้องการ core.jar จาก zxing คุณสามารถข้ามกระบวนการนั้นและรับJAR ที่สร้างไว้ล่วงหน้าได้จากหน้า Wiki เริ่มต้น

ZXing ล่าสุด (2.2) ไม่มี core.jar ใต้โฟลเดอร์หลัก แต่คุณสามารถรับ core.jar ได้จากที่เก็บ zxing Maven ที่นี่


2

ทีละขั้นตอนในการตั้งค่า zxing 3.2.1 ใน eclipse

  1. ดาวน์โหลด zxing-master.zip จาก " https://github.com/zxing/zxing "
  2. เปิดเครื่องรูด zxing-master.zip ใช้ eclipse เพื่อนำเข้าโครงการ "android" ใน zxing-master
  3. ดาวน์โหลด core-3.2.1.jar จาก " http://repo1.maven.org/maven2/com/google/zxing/core/3.2.1/ "
  4. สร้างโฟลเดอร์ "libs" ในโครงการ "android" และวาง cor-3.2.1.jar ลงในโฟลเดอร์ libs
  5. คลิกที่โครงการ: เลือก "Properties" -> "Java Compiler" เพื่อเปลี่ยนระดับเป็น 1.7 จากนั้นคลิกที่ "Android" เปลี่ยน "Project build target" เป็น android 4.4.2+ เนื่องจากใช้ 1.7 ต้องมีการคอมไพล์ด้วย Android 4.4
  6. หาก "CameraConfigurationUtils.java" ไม่มีอยู่ใน "zxing-master / android / app / src / main / java / com / google / zxing / client / android / camera /" คุณสามารถคัดลอกจาก "zxing-master / android-core / src / main / java / com / google / zxing / ไคลเอนต์ / android / camera /" และวางโครงการของคุณ
  7. ทำความสะอาดและสร้างโครงการ หากโครงการของคุณแสดงข้อผิดพลาดเกี่ยวกับ "สลับ - ตัวพิมพ์ใหญ่" คุณควรเปลี่ยนเป็น "if - else"
  8. เสร็จ ทำความสะอาดและสร้างโครงการ
  9. ลิงค์อ้างอิง: การใช้ ZXing เพื่อสร้างแอปสแกนบาร์โค้ดสำหรับ Android

2

ฉันลองใช้วิธีที่เป็นไปได้ทั้งหมดเพื่อให้บรรลุเป้าหมายนี้และจากนั้นฉันก็ค้นพบ xZing โดย JourneyApps รุ่นย่อ ฉันได้แจ้งว่าสำหรับ eclipse และแบ่งปันกับ GitHub

หากคุณกำลังใช้ eclipse ให้ใช้โครงการนี้: -

https://github.com/hiteshsahu/XZing-Barcode-Scanner-Minified-Eclipse

หากคุณใช้สตูดิโอใช้โครงงานนี้: -

https://github.com/journeyapps/zxing-android-embedded

ข้อดี

  1. เครื่องสแกนบาร์โค้ด Inbuilt ในแอพของคุณไม่จำเป็นต้องติดตั้งแอพของบุคคลที่สามโดยใช้ playstore

  2. คุณไม่จำเป็นต้องสับสนระหว่างคอร์, ไคลเอ็นต์ Android ฯลฯ ไหเพียงวางแพ็คเกจนี้และเค้าโครงที่เกี่ยวข้องในโครงการของคุณและคุณก็พร้อมที่จะไป ต้องใช้ Jar เท่านั้นคือcom.google.zxing: core: 3.2.0ซึ่งคุณสามารถดาวน์โหลดได้

    http://mvnrepository.com/artifact/com.google.zxing/core/3.2.0

  3. ไม่จำเป็นต้องเพิ่มแพ็คเกจจำนวนมากดูภาพด้านล่างเพื่อทำการเปรียบเทียบ

ก่อน: -

ป้อนคำอธิบายรูปภาพที่นี่

หลังจาก: -

ป้อนคำอธิบายรูปภาพที่นี่

  1. ส่วนที่สำคัญที่สุดคือพวกมันสามารถปรับแต่งได้สูงเช่น คุณสามารถเพิ่มแสงแฟลชใช้ในส่วนและเปลี่ยนการสนับสนุน

  2. คุณสามารถใช้กิจกรรมจับภาพนี้ในแอพ Cordovaสำหรับการสแกนบาร์โค้ด

กิจกรรมการจับภาพของคุณในรายการแอปจะมีลักษณะเช่นนี้

  <activity
            android:name="com.journeyapps.barcodescanner.CaptureActivity"
            android:clearTaskOnLaunch="true"
            android:configChanges="orientation|keyboardHidden"
            android:exported="false"
            android:screenOrientation="fullSensor"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >
            <intent-filter>
                <action android:name="com.google.zxing.client.android.SCAN" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

และปลั๊กอินจะมีลักษณะเช่นนี้

public class BarcodeScanner extends CordovaPlugin {
    public static final int REQUEST_CODE = 0x0ba7c0de;

    private static final String SCAN = "scan";
    private static final String CANCELLED = "cancelled";
    private static final String FORMAT = "format";
    private static final String TEXT = "text";
    private static final String SCAN_INTENT = "com.google.zxing.client.android.SCAN";

    private static final String LOG_TAG = "BarcodeScanner";

    private CallbackContext callbackContext;

    /**
     * Constructor.
     */
    public BarcodeScanner() {


    }

    /**
     * Executes the request.
     *
     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
     *     cordova.getThreadPool().execute(runnable);
     *
     * To run on the UI thread, use:
     *     cordova.getActivity().runOnUiThread(runnable);
     *
     * @param action          The action to execute.
     * @param args            The exec() arguments.
     * @param callbackContext The callback context used when calling back into JavaScript.
     * @return                Whether the action was valid.
     *
     * @sa https://github.com/apache/cordova-android/blob/master/framework/src/org/apache/cordova/CordovaPlugin.java
     */
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
        this.callbackContext = callbackContext;
        if (action.equals(SCAN)) {
            scan(args);
        } else {
            return false;
        }
        return true;
    }

    /**
     * Starts an intent to scan and decode a barcode.
     */
    public void scan(JSONArray args) {
        Intent intentScan = new Intent(SCAN_INTENT);
        intentScan.addCategory(Intent.CATEGORY_DEFAULT);

        // add config as intent extras
        if(args.length() > 0) {

            JSONObject obj;
            JSONArray names;
            String key;
            Object value;

            for(int i=0; i<args.length(); i++) {

                try {
                    obj = args.getJSONObject(i);
                } catch(JSONException e) {
                    Log.i("CordovaLog", e.getLocalizedMessage());
                    continue;
                }

                names = obj.names();
                for(int j=0; j<names.length(); j++) {
                    try {
                        key = names.getString(j);
                        value = obj.get(key);

                        if(value instanceof Integer) {
                            intentScan.putExtra(key, (Integer)value);
                        } else if(value instanceof String) {
                            intentScan.putExtra(key, (String)value);
                        }

                    } catch(JSONException e) {
                        Log.i("CordovaLog", e.getLocalizedMessage());
                        continue;
                    }
                }
            }

        }

        // avoid calling other phonegap apps
        intentScan.setPackage(this.cordova.getActivity().getApplicationContext().getPackageName());

        this.cordova.startActivityForResult((CordovaPlugin) this, intentScan, REQUEST_CODE);
    }

    /**
     * Called when the barcode scanner intent completes.
     *
     * @param requestCode The request code originally supplied to startActivityForResult(),
     *                       allowing you to identify who this result came from.
     * @param resultCode  The integer result code returned by the child activity through its setResult().
     * @param intent      An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                JSONObject obj = new JSONObject();
                try {
                    obj.put(TEXT, intent.getStringExtra("SCAN_RESULT"));
                    obj.put(FORMAT, intent.getStringExtra("SCAN_RESULT_FORMAT"));
                    obj.put(CANCELLED, false);
                } catch (JSONException e) {
                    Log.d(LOG_TAG, "JSONException "+e.getMessage());
                }
                this.callbackContext.success(obj);
            } else if (resultCode == Activity.RESULT_CANCELED) {
                this.callbackContext.success("");
            } else {
                this.callbackContext.error("Technical Problem");
            }
        }
    }
}

การรวมที่มีความสุข !!


2

พวก zxing ทำให้การสร้างโปรเจค android ด้วย 1.7 นั้นง่ายขึ้น มันไม่เจ็บปวดอย่างที่เคยเป็น นี่เป็นบล็อกด่วนสำหรับทุกคนที่ต้องการสร้างโครงการ zxing สำหรับ Android อย่างรวดเร็ว

  • ชำระเงินที่มา zxing จาก zxing.org
  • สร้างโครงการ Android บน eclipse ของคุณ
  • ลบ main.xml
  • คลิกขวาที่ไดเรกทอรี“ src” แล้วกดนำเข้า เรียกดูไดเรกทอรีต่อไปนี้ตามลำดับที่กล่าวถึง เมื่อคุณเพิ่มลงในการนำเข้าทีละตัวให้แน่ใจว่าคุณมีไดเรกทอรี src ในฟิลด์แก้ไขของตัวช่วยสร้างการนำเข้า และให้คุณเลือกเฉพาะไดเรกทอรี“ com” บนแผนผังไดเรกทอรีด้านซ้าย อย่าเลือก src
  • แกน
  • หุ่นยนต์บูรณาการ
  • หุ่นยนต์
  • ตรวจสอบให้แน่ใจว่า android sdk version ของคุณคือ 9 จะมีอะไรน้อยลงและ androidmanifest.xml จะร้องไห้
  • Strings.xml ในภาษาใดภาษาหนึ่งจะเปลเพียงใส่ / ก่อนอักขระ '

โครงการ android สำหรับ zxing 1.7 (ชำระเงินวันที่ 20 มิถุนายน)

http://www.4shared.com/file/bFx8Y5Ys/zXingJune2010.html (ไม่สามารถใช้ได้อีกต่อไป )


2

เหตุใดจึงต้องใช้ lib ภายนอกเมื่อใช้บริการ Google Play (ตั้งแต่รุ่น 7.8.0) ) มีตัวถอดรหัสบาร์โค้ด


1
คุณไม่สามารถติดตั้งบริการ Google Play ในประเทศจีนเนื่องจาก Google ถูกบล็อก
XièJìléi

หากคุณติดตั้งบริการ Google Play อย่างโชคดีคุณยังคงไม่สามารถใช้งานได้ในประเทศจีนเนื่องจาก Google ถูกบล็อก
XièJìléi

2

ฉันเพิ่งเขียนวิธีที่ถอดรหัสบาร์โค้ดBitmapเพื่อStringสร้าง

มันทำสิ่งที่ต้องการโดยไม่ต้องCaptureActivity...

ดังนั้นหนึ่งสามารถข้ามandroid-integrationไลบรารีในbuild.gradle:

dependencies {
    // https://mvnrepository.com/artifact/com.google.zxing
    compile('com.google.zxing:core:3.3.0')
    compile('com.google.zxing:android-core:3.3.0')
}

วิธีการดังต่อไปนี้ (ซึ่งจริง ๆ แล้วถอดรหัสบาร์โค้ดที่สร้างขึ้นภายในการทดสอบ jUnit):

import android.graphics.Bitmap;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.Result;

protected String decode(Bitmap bitmap) {

    MultiFormatReader reader = new MultiFormatReader();
    String barcode = null;

    int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()];
    bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
    LuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray);
    BinaryBitmap binary = new BinaryBitmap(new HybridBinarizer(source));

    try {

        Result result = reader.decode(binary);
        // BarcodeFormat format = result.getBarcodeFormat(); 
        // ResultPoint[] points = result.getResultPoints();
        // byte[] bytes = result.getRawBytes(); 
        barcode = result.getText();

    } catch (NotFoundException e) {
        e.printStackTrace();
    }
    return barcode;
}


0

ฉันเพิ่งใช้ google mobile vision ใน ios และ android ฉันแนะนำอย่างยิ่งให้ใช้การสแกนบาร์โค้ดของ Google มันค่อนข้างตอบสนองต่อทิศทางและเวลาในการประมวลผลที่ค่อนข้างเร็ว เรียกว่า Google Mobile Vision

API เครื่องสแกนบาร์โค้ดตรวจจับบาร์โค้ดในเวลาจริงในทิศทางใดก็ได้ นอกจากนี้คุณยังสามารถตรวจจับและแยกบาร์โค้ดหลายรูปแบบในเวลาเดียวกัน

https://developers.google.com/vision/

https://codelabs.developers.google.com/codelabs/bar-codes/#0


0

วิธีที่ง่ายกว่ามาก

เพียงรวมการพึ่งพาในไฟล์ gradle ระดับแอปของคุณ

compile 'com.journeyapps:zxing-android-embedded:3.0.1@aar'
compile 'com.google.zxing:core:3.2.0'  

กำหนดปุ่มเดียวในไฟล์ xml ของคุณและเขียนรหัสด้านล่างในไฟล์ Java ใน OnCreate () และด้านในปุ่มฟังของ OnClick

new IntentIntegrator(this).initiateScan();

และเขียนโค้ดด้านล่างหลังจาก OnCreate () ของไฟล์ Java

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if(result != null) {
        if(result.getContents() == null) {
            Log.d("MainActivity", "Cancelled scan");
            Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
        } else {
            Log.d("MainActivity", "Scanned");
            String st_scanned_result = result.getContents();
            Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();

        }
    }

}

st_scanned_resultไม่ได้กำหนดไว้ที่นี่
kelalaka

นั่นคือตัวแปรทั่วโลกประเภทสตริง หากคุณไม่ได้ใช้ผลการสแกนด้านนอกของ onActivtyResult () นี้คุณสามารถกำหนดมันแบบโลคัล เช่นเดียวกับ String st_scanned_result = result.getContents (); ฉันได้อัพเดทมันแล้วนะ chk
ธารา

0

2020 อัปเดต: เพียงเพิ่มไฟล์นี้ในไฟล์ Gradle ของคุณ มันทำงานได้อย่างสมบูรณ์แบบ!

repositories {
   jcenter()
}
implementation 'me.dm7.barcodescanner:zxing:1.9.13'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.