将ZXing库直接集成到我的Android应用程序中

App*_*Dev 138 android barcode barcode-scanner zxing

我只是在绝望中写这篇文章:)我被指派为Android 1.6手机制作一个独立的条形码扫描仪(作为概念证明).

为此,我发现了ZXing库.

我用谷歌搜索,在StackOverflow上阅读相关主题,使用常见的等等.似乎没有任何帮助,我只是不能在这个精神封锁上打个洞:/

我知道可以使用lib,并创建自己的独立条形码扫描仪.我读过使用Zxing人提供的"条码扫描器",这是迄今为止最简单的解决方案(通过Intent).不幸的是,这不是一个选项,需要一个独立的应用程序.

总结一下我的问题:

  1. 如何通过Eclipse将ZXing源库集成到我的Android代码项目中?
  2. 集成时...如何利用lib,"加载"扫描功能?
  3. 几乎没有步骤指南,因为我刚开始在Eclipse中工作.

我试图让我的代码项目依赖于ZXing源文件夹中的Android文件夹.当我这样做时,会出现一些错误,主要涉及'org.apache'(??)

我只是想不出来......所以一些提示将是最有帮助的.

提前谢谢:)

App*_*Dev 126

UPDATE! - 求助+指南

我已经设法弄明白:)在下面你可以阅读逐步指南,所以它希望可以帮助其他人遇到与我相同的问题;)

  1. 安装Apache Ant - (有关配置帮助,请参阅此YouTube视频)
  2. 从ZXing主页下载ZXing源并解压缩
  3. 使用Windows Commandline(Run-> CMD)导航到下载的根目录zxing src.
  4. 在命令行窗口中 - ant -f core/build.xml输入按回车键让Apache发挥作用[ 有问题吗?]
  5. 根据您刚提取的目录中的android文件夹输入Eclipse - > new Android Project
  6. 右键单击项目文件夹 - >属性 - > Java构建路径 - >库 - >添加外部JAR ...
  7. 导航到新解压缩的文件夹并打开核心目录并选择core.jar...按Enter键!

现在您只需更正翻译和AndroidManifest.xml文件中的一些错误:)现在您可以愉快地编译,现在您将拥有一个基于ZXing源的独立条码扫描器应用程序;)

快乐的编码人 - 我希望它可以帮助别人:)

  • AndroidManifest.xml文件中没有错误,也没有翻译错误.但是,最新的Android SDK存在兼容性问题.如果您使用它,您必须使用SVN以后的源代码. (6认同)
  • 好吧,现在我知道为什么了。如果有人也想知道,请参阅http://stackoverflow.com/questions/4854442/embed-zxing-library-without-using-barcode-scanner-app (2认同)

Wes*_*sam 83

以下是如何使用ZXing库生成和显示QR代码的分步指南,无需安装第三方应用程序. 注意:您不必使用ANT或任何其他构建工具构建ZXing.该文件core.jar在已发布的zip存档中可用(如下所示).

  1. 下载ZXing最新版本.- (ZXing-*.zip)
  2. 解压缩此zip存档并core.jarcore/目录下找到.
  3. 如果您使用的是Eclipse IDE,请拖放core.jarlibsAndroid项目的目录中.询问时,选择复制.
  4. 将下面(Contents.java&QRCodeEncoder.java)下面给出的两个类复制到Android项目的主程序包中.
  5. ImageView如果您还没有生成的QR码,请在"活动"中创建一个项目以显示生成的QR码.下面给出一个例子:
  6. 使用下面的代码片段以位图格式生成QR码并将其显示在ImageView.

以下是ImageView要添加到Activity布局XML文件的元素:

<ImageView 
    android:id="@+id/qrCode"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="50dp"
    android:layout_centerHorizontal="true"/>
Run Code Online (Sandbox Code Playgroud)

代码段:

// 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();
}
Run Code Online (Sandbox Code Playgroud)

这是 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
    };
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 由于某种原因,最新的ZXing没有core.jar.我不得不为它下载2.1. (13认同)
  • core.jar在Maven版本库中单独提供,对于版本2.2,链接是http://repo1.maven.org/maven2/com/google/zxing/core/2.2/core-2.2.jar (12认同)
  • Zxing 2.3.0 core.jar:http://repo1.maven.org/maven2/com/google/zxing/core/2.3.0/ (12认同)
  • @Wesam,这真的很有帮助.但是你也可以提供代码,反之亦然.我的意思是,将QR码转换回String? (2认同)

Kar*_*oly 15

compile 'com.google.zxing:core:2.3.0'
Run Code Online (Sandbox Code Playgroud)

不幸的是没有为我工作.

这对我有用:

dependencies {
   compile 'com.journeyapps:zxing-android-embedded:3.0.1@aar'
   compile 'com.google.zxing:core:3.2.0'
}
Run Code Online (Sandbox Code Playgroud)

请在此处找到链接:https: //github.com/journeyapps/zxing-android-embedded


小智 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
Run Code Online (Sandbox Code Playgroud)

然后将您的JAVA_HOME环境变量设置为正确的java文件夹.我在我的(Windows)中找到了tools.jar:

C:\Program Files\Java\jdk1.6.0_21\lib
Run Code Online (Sandbox Code Playgroud)

所以我设置JAVA_HOME为:

C:\Progra~1\Java\jdk1.6.0_25
Run Code Online (Sandbox Code Playgroud)

我在某个网站上发现的语法较短的原因是:

"强烈建议您选择一个在路径名中不包含空格的安装目录(例如,不要安装在C:\ Program Files中).如果在这样的目录中安装了Java,那么设置JAVA_HOME至关重要环境变量到不包含空格的路径(例如,C:\ Progra~1);如果不这样做将导致某些依赖于JAVA_HOME值的程序抛出异常.

然后我重新启动cmd(重要的是因为DOS shell在启动时只读取env变量,因此更改env var将要求您使用新的shell来获取更新的值)

最后ant -f core/build.xml工作了.

  • 将`tools.jar`复制到`C:\ Program Files\Java\jre6\lib`也对我有用.. (3认同)

Ale*_*ber 11

由于一些答案已经过时,我想提供我自己的答案 -

按照Wiki的建议将ZXing库集成到Android应用程序中,您需要在项目中添加2个Java文件:

然后在Android Studio中将以下行添加到build.gradle文件中:

dependencies {
    ....
    compile 'com.google.zxing:core:3.2.1'
}
Run Code Online (Sandbox Code Playgroud)

或者,如果仍然使用带有ADT-plugin的Eclipse,请将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();
}
Run Code Online (Sandbox Code Playgroud)

生成的应用程序将要求安装并启动ZXing的Barcode Scanner应用程序(扫描后将自动返回到您的应用程序):

条码扫描器应用程序

此外,如果您想构建并运行ZXing Test应用程序作为您自己的应用程序的灵感:

ZXing测试应用

然后你需要来自GitHub的 4个Java文件:

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

来自Maven存储库的 3个Jar文件:

  • core.jar添加
  • Android的core.jar添加
  • Android的integration.jar

(您可以自己构建Jar文件mvn package- 如果您从GitHub查看ZXing 并在您的计算机上安装antmaven工具).

注意:如果您的项目无法识别Jar文件,则可能需要在项目属性中启动Java版本:

属性截图

  • 我担心错过了问题的重点:-(重点是不依赖于外部应用程序.这说明如何使用外部应用程序?请参阅问题标题"直接在" (3认同)
  • 这是一个很棒的答案! (2认同)

Kev*_*Tan 5

compile 'com.google.zxing:core:2.3.0' 
Run Code Online (Sandbox Code Playgroud)

进入您的 Gradle 依赖项。就这么简单。在使用 Android Studio 和 Gradle 构建系统之前。