Integration der ZXing-Bibliothek direkt in meine Android-Anwendung


140

Ich schreibe dies in bloßer Verzweiflung :) Ich wurde beauftragt, einen eigenständigen Barcode-Scanner (als Proof of Concept) für ein Android 1.6-Telefon zu erstellen.

Dafür habe ich die ZXing-Bibliothek entdeckt.

Ich habe gegoogelt, verwandte Themen hier auf StackOverflow gelesen, verwendet allgemeinen Sinn und so weiter. Nichts schien geholfen zu haben, und ich kann einfach kein Loch in diese Mentale-Blockade schlagen: /

Ich weiß, dass es möglich ist, die Bibliothek zu verwenden und Ihren eigenen eigenständigen Barcode-Scanner zu erstellen. Ich habe gelesen, dass die Verwendung des von den Zxing-Leuten bereitgestellten "Barcode-Scanners" bei weitem die einfachste Lösung ist (über Intent). Leider ist dies keine Option und eine eigenständige App ist erwünscht.

Um mein Problem zusammenzufassen:

  1. Wie kann ich ZXing Source Lib über Eclipse in mein Android Code-Projekt integrieren?
  2. Wenn integriert ... wie kann man die Bibliothek nutzen, um die Scanfunktion zu "laden"?
  3. Eine Schritt-für-Schritt-Anleitung wird fast bevorzugt, da ich gerade angefangen habe, in Eclipse zu arbeiten.

Ich habe versucht, mein Codeprojekt vom Android-Ordner des ZXing-Quellordners abhängig zu machen. Wenn ich das tue, tauchen eine Handvoll Fehler auf, hauptsächlich in Bezug auf 'org.apache' (??)

Ich kann es einfach nicht herausfinden ... also wären ein paar Hinweise am hilfreichsten.

Im Voraus danke :)


Ich glaube, was Sie tun wollten, finden Sie hier: stackoverflow.com/questions/4854442/…
Danny Remington - OMS

ZXing ist nicht die einzige Möglichkeit, einen Barcode zu lesen. Ab 2016 ist es viel einfacher, die Android-Barcode-API zu verwenden .
Dan Dascalescu

Antworten:


127

AKTUALISIEREN! - Gelöst + Leitfaden

Ich habe es geschafft, es herauszufinden :) Und unten können Sie eine Schritt-für-Schritt-Anleitung lesen, damit sie hoffentlich anderen bei dem gleichen Problem helfen kann, das ich hatte;)

  1. Installieren Sie Apache Ant - ( Konfigurationshilfe finden Sie in diesem YouTube-Video. )
  2. Laden Sie die ZXing-Quelle von der ZXing-Homepage herunter und extrahieren Sie sie
  3. Navigieren Sie mit der Windows-Befehlszeile (Run-> CMD) zum Stammverzeichnis des heruntergeladenen zxing src.
  4. Im Kommandozeilenfenster - Geben Sie ant -f core/build.xmldie Eingabetaste ein und lassen Sie Apache arbeiten. Es ist magisch [ Probleme? ]]
  5. Geben Sie Eclipse -> neues Android-Projekt ein, basierend auf dem Android-Ordner in dem Verzeichnis, das Sie gerade extrahiert haben
  6. Klicken Sie mit der rechten Maustaste auf den Projektordner -> Eigenschaften -> Java-Erstellungspfad -> Bibliothek -> Externe JARs hinzufügen ...
  7. Navigieren Sie zum neu extrahierten Ordner, öffnen Sie das Kernverzeichnis und wählen Sie core.jar... drücken Sie die Eingabetaste!

Jetzt müssen Sie nur noch ein paar Fehler in den Übersetzungen und in der Datei AndroidManifest.xml korrigieren :) Jetzt können Sie problemlos kompilieren und haben jetzt eine funktionierende eigenständige Barcode-Scanner-App, die auf der ZXing-Quelle basiert;)

Happy Coding Jungs - ich hoffe es kann anderen helfen :)


Großartige Zusammenfassung! Können Sie einige Details zu dem hinzufügen, was Sie in der AndroidManifest.xmlDatei bearbeitet haben ? Ich sehe bei der Prüfung keine Fehler in dieser Datei. Vielen Dank!
Brian Armstrong

7
Es gibt weder Fehler in der Datei AndroidManifest.xml noch in den Übersetzungen. Es gibt jedoch Kompatibilitätsprobleme im neuesten Android SDK. Wenn Sie es verwenden, müssen Sie späteren Quellcode von SVN verwenden.
Sean Owen

Hallo, ich habe versucht, eine andere Anwendung für das QR-Scannen als eigenständige App zu entwickeln, ohne eine QR Droid- oder Barcode-Scanner-App zu verwenden. Sind die Schritte, die Sie erwähnt haben, um genau das zu tun, oder verwenden Sie immer noch eine andere App über Absichten oder irgendetwas?
Kumar

1
Das Zip-Paket von code.google.com/p/zxing/downloads/list enthält das "Core" -Verzeichnis sowie "Android" und "Android-Integration". Was ist der Grund, warum Sie "Kern" verwendet haben?
Michał K

1
Okay, jetzt weiß ich warum. Wenn sich jemand auch gefragt hat, siehe stackoverflow.com/questions/4854442/…
Michał K

83

Hier finden Sie eine schrittweise Anleitung zum Generieren und Anzeigen von QR-Code mithilfe der ZXing-Bibliothek, ohne die Drittanbieteranwendung installieren zu müssen. Hinweis: Sie müssen ZXing nicht mit ANT oder einem anderen Build-Tool erstellen. Die Datei core.jarist im freigegebenen Zip-Archiv verfügbar (siehe unten).

  1. Laden Sie die neueste Version von ZXing herunter . - ( ZXing-*.zip)
  2. Extrahieren Sie dieses Zip-Archiv und suchen Sie core.jarunter core/Verzeichnis.
  3. Wenn Sie die Eclipse-IDE verwenden, ziehen Sie sie per Drag & Drop core.jarin das libsVerzeichnis Ihres Android-Projekts. Wenn Sie dazu aufgefordert werden, wählen Sie Kopieren .
  4. Kopieren Sie die beiden unten angegebenen Klassen ( Contents.java& QRCodeEncoder.java) in das Hauptpaket Ihres Android-Projekts.
  5. Erstellen Sie ein ImageViewElement in Ihrer Aktivität, um den generierten QR-Code anzuzeigen, falls Sie noch keinen haben. Ein Beispiel ist unten angegeben:
  6. Verwenden Sie das folgende Codefragment, um den QR-Code im Bitmap-Format zu generieren und in einem anzuzeigen ImageView.

Hier ist ein ImageViewElement, das Sie Ihrer XML-Datei für das Aktivitätslayout hinzufügen können:

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

Code-Auszug:

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

Hier ist 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
    };
}

Und 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
Das neueste ZXing hat aus irgendeinem Grund keine core.jar. Ich musste 2.1 dafür herunterladen.
Capcom

12
core.jar ist separat im Maven Release Repository verfügbar. Für Version 2.2 lautet der Link repo1.maven.org/maven2/com/google/zxing/core/2.2/core-2.2.jar
Nantoka


1
Ihre encodeAsBitmap () -Methode gibt null zurück, wenn sie nicht geändert wurde, oder schlägt mit einer NullPointerException fehl, wenn ich die Zeile auskommentiere, die null zurückgibt. Ich bin neu in dieser Bibliothek. Was mache ich falsch?
KG6ZVP

2
@ Wesam, es war wirklich hilfreich. Kannst du aber auch den Code bereitstellen, wo das Gegenteil möglich ist? Ich meine, den QR-Code zurück in den String konvertieren?
Shaon Hasan

15

Das

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

hat bei mir leider nicht funktioniert.

Das hat bei mir funktioniert:

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

Den Link finden Sie hier: https://github.com/journeyapps/zxing-android-embedded


1
Diese Antwort wird durch die anderen Antworten hier in den Schatten gestellt. Die meisten mit Screenshots und so. Das ist eine Schande, denn dies ist die einzige Antwort, die tatsächlich funktioniert! Achten Sie auf diesen. Was er nicht erwähnt hat, ist, dass das verknüpfte Projekt ein Zweig ist, in dem jemand diese schwierige Bibliothek zu einer einfach (und tatsächlich einfach zu verwendenden) Bibliothek gemacht hat. Laden Sie einfach das Kernglas aus dem normalen ZXING-Projekt herunter und los geht's. Hat sogar Beispiele !!!!
StarWind0

1
Ich wünschte, ich könnte mehr Gegenstimmen geben. Sie haben keine Ahnung, wie oft ich im Laufe der Jahre versucht habe, dies bei verschiedenen Projekten herauszufinden.
StarWind0

1
Ich bin glücklich, Jungs zu dienen :)
Karoly

11

Haben Sie Probleme mit ANT? Weiter lesen

Wenn ant -f core/build.xml so etwas sagt wie:

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

Setzen Sie dann Ihre JAVA_HOMEUmgebungsvariable auf den richtigen Java-Ordner. Ich habe tools.jar in meinem (für Windows) gefunden:

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

Also stellte ich meine JAVA_HOMEauf:

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

Der Grund für die kürzere Syntax, die ich an einer Stelle gefunden habe, die besagt:

"Es wird dringend empfohlen, ein Installationsverzeichnis auszuwählen, das keine Leerzeichen im Pfadnamen enthält (z. B. NICHT in C: \ Programme installieren). Wenn Java in einem solchen Verzeichnis installiert ist, ist es wichtig, JAVA_HOME festzulegen Umgebungsvariable für einen Pfad, der keine Leerzeichen enthält (z. B. C: \ Progra ~ 1). Andernfalls werden von einigen Programmen Ausnahmen ausgelöst, die vom Wert von JAVA_HOME abhängen. "

Ich habe dann cmd neu gestartet (wichtig, da die DOS-Shell beim Starten nur env-Variablen liest. Wenn Sie also eine env-Variable ändern, müssen Sie eine neue Shell verwenden, um den aktualisierten Wert zu erhalten.)

und schließlich hat das ant -f core/build.xmlfunktioniert.


11

Da einige der Antworten veraltet sind, möchte ich meine eigenen angeben -

Um die ZXing-Bibliothek wie vom Wiki vorgeschlagen in Ihre Android-App zu integrieren , müssen Sie Ihrem Projekt zwei Java-Dateien hinzufügen:

Fügen Sie dann in Android Studio die folgende Zeile zur Datei build.gradle hinzu :

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

Wenn Sie Eclipse weiterhin mit dem ADT-Plugin verwenden, fügen Sie die Datei core.jar zum Unterverzeichnis libs Ihres Projekts hinzu (hier Vollbild-Windows und Vollbild-Mac ):

Windows-Screenshot

Fügen Sie diesen Code schließlich zu Ihrer MainActivity.java hinzu :

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

Die resultierende App fordert Sie auf, die Barcode-Scanner-App von ZXing zu installieren und zu starten (die nach dem Scannen automatisch zu Ihrer App zurückkehrt):

Barcode Scanner App

Wenn Sie außerdem die ZXing Test-App als Inspiration für Ihre eigene App erstellen und ausführen möchten :

ZXing Test App

Dann benötigen Sie 4 Java-Dateien von GitHub :

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

Und 3 Jar-Dateien aus dem Maven-Repository :

  • core.jar
  • android-core.jar
  • android-integration.jar

(Sie können die JAR - Dateien erstellen , sich mit mvn package- wenn Ihr Check - out ZXing von GitHub und installieren ant und maven Tools auf Ihrem Computer).

Hinweis: Wenn Ihr Projekt die Jar-Dateien nicht erkennt, müssen Sie möglicherweise die Java-Version in den Projekteigenschaften aktualisieren:

Eigenschaften Screenshot


2
Das ist eine fantastische Antwort!
Paresh Mayani

3
Ich befürchte, dies hat den Punkt der Frage verfehlt :-( Der Punkt war, sich nicht auf eine externe Anwendung zu verlassen. Dies zeigt, wie man .. eine externe Anwendung verwendet? Siehe in
Fragetitel

5

Stellen

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

in Ihre Gradle-Abhängigkeiten. So einfach ist das. Vor der Verwendung von Android Studio und Gradle Build System.


Richtig! Das ist die wirkliche Lösung im Jahr 2015. Übrigens. Die aktuelle Version ist 3.2.0
Funcoder

Hat das bei irgendjemandem funktioniert? IntentIntegrator konnte immer noch nicht gefunden werden
Karoly

Sie sollten die Dateien IntentIntegrator.java und IntentResult.java manuell in Ihr Android Studio-Projekt kopieren .
Alexander Farber

4

Hast du die Wiki-Seiten auf der zxing-Website gesehen? Es scheint, dass Sie GettingStarted , DeveloperNotes und ScanningViaIntent hilfreich finden.


Entschuldigung ... es war nicht ganz die Hilfe, nach der ich gesucht habe :) Aber heute hatte ich einen Durchbruch: PI hat es selbst herausgefunden;) Ein Leitfaden für andere Zuschauer mit dem gleichen Problem wird sofort veröffentlicht :)
AppDev


2

Schritt für Schritt, um zxing 3.2.1 in Eclipse einzurichten

  1. Laden Sie zxing-master.zip von " https://github.com/zxing/zxing " herunter.
  2. Entpacken Sie zxing-master.zip. Verwenden Sie Eclipse, um das "Android" -Projekt in zxing-master zu importieren
  3. Laden Sie core-3.2.1.jar von " http://repo1.maven.org/maven2/com/google/zxing/core/3.2.1/ " herunter.
  4. Erstellen Sie den Ordner "libs" im Projekt "android" und fügen Sie cor-3.2.1.jar in den Ordner "libs" ein
  5. Klicken Sie auf Projekt: Wählen Sie "Eigenschaften" -> "Java Compiler", um die Stufe auf 1.7 zu ändern. Klicken Sie dann auf "Android" und ändern Sie "Project Build Target" in Android 4.4.2+, da für die Verwendung von 1.7 das Kompilieren mit Android 4.4 erforderlich ist
  6. Wenn "CameraConfigurationUtils.java" in "zxing-master / android / app / src / main / java / com / google / zxing / client / android / camera /" nicht vorhanden ist. Sie können es aus "zxing-master / android-core / src / main / java / com / google / zxing / client / android / camera /" kopieren und in Ihr Projekt einfügen.
  7. Projekt reinigen und bauen. Wenn in Ihrem Projekt ein Fehler bezüglich "switch - case" angezeigt wird, sollten Sie diesen in "if - else" ändern.
  8. Abgeschlossen. Projekt reinigen und bauen.
  9. Referenzlink: Verwenden von ZXing zum Erstellen einer Android-Barcode-Scan-App

2

Ich habe alle möglichen Wege ausprobiert, um dies zu erreichen, und dann die Minified-Version von xZing von JourneyApps entdeckt. Ich habe das für Eclipse portiert und auf GitHub geteilt.

Wenn Sie Eclipse verwenden, verwenden Sie dieses Projekt: -

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

Wenn Sie Studio verwenden, verwenden Sie dieses Projekt: -

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

Vorteile

  1. Der in Ihrer App integrierte Barcode-Scanner ist nicht erforderlich, um Apps von Drittanbietern über den Playstore zu installieren.

  2. Sie müssen nicht zwischen Core-, Android-Client- usw. Gläsern verwechselt werden. Legen Sie einfach diese Pakete ab und legen Sie Layouts in Ihrem Projekt fest, und schon kann es losgehen. Nur Jar erforderlich ist com.google.zxing: core: 3.2.0, von dem Sie herunterladen können

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

  3. Keine Notwendigkeit, Tonnen von Paketen hinzuzufügen, siehe Bilder unten zum Vergleich

Vor :-

Geben Sie hier die Bildbeschreibung ein

Nach dem :-

Geben Sie hier die Bildbeschreibung ein

  1. Der wichtigste Teil ist, dass sie hochgradig anpassbar sind, dh. Sie können Blitzlicht hinzufügen, es in Fragmenten verwenden und die Änderung der Ausrichtung unterstützen.

  2. Sie können diese Capture-Aktivität in der Cordova App zum Scannen von Barcodes verwenden.

Ihre Erfassungsaktivität im App-Manifest würde folgendermaßen aussehen

  <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>

und Plugin wird so aussehen

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");
            }
        }
    }
}

Glückliche Integration !!


2

Die zxing-Leute haben es einfacher gemacht, ein Android-Projekt mit 1.7 zu erstellen. Es ist nicht mehr so ​​schmerzhaft wie früher. Dies ist ein kurzer Blog für alle, die schnell ein zxing-Projekt für Android erstellen möchten.

  • Überprüfen Sie die zxing-Quellen von zxing.org
  • Erstellen Sie ein Android-Projekt auf Ihrer Eclipse
  • Löschen Sie main.xml
  • Klicken Sie mit der rechten Maustaste auf das Verzeichnis "src" und klicken Sie auf "Importieren". Navigieren Sie in der angegebenen Reihenfolge zu den folgenden Verzeichnissen. Stellen Sie beim Hinzufügen nacheinander für den Import sicher, dass sich das Verzeichnis src im Bearbeitungsfeld des Importassistenten befindet. Und dass Sie nur das Verzeichnis "com" im linken Verzeichnisbaum auswählen. Wählen Sie nicht src.
  • Ader
  • Android-Integration
  • Android
  • Stellen Sie sicher, dass Ihre Android SDK-Version 9 ist, alles weniger und androidmanifest.xml wird weinen.
  • Strings.xml in einer der Sprachen wird krippen, setzen Sie einfach ein / vor das Zeichen '

Ein Android-Projekt für zxing 1.7 (20. Juni Checkout).

http://www.4shared.com/file/bFx8Y5Ys/zXingJune2010.html ( NICHT MEHR VERFÜGBAR )


2

Warum eine externe Bibliothek verwenden, wenn Google Play Services (seit Version 7.8.0 ) einen Barcode-Decoder enthält ?


1
Sie können Google Play-Dienste in China nicht installieren, da Google blockiert ist.
Xiè Jìléi

Wenn Sie zum Glück Google Play-Dienste installiert haben, können Sie diese in China immer noch nicht verwenden, da Google blockiert ist.
Xiè Jìléi

2

Ich schrieb eine Methode, die Bar-Codes erzeugt decodiert, Bitmapauf String.

Es macht genau das, was angefordert wird, nur ohne die CaptureActivity...

Daher kann man die android-integrationBibliothek überspringen in 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')
}

Die folgende Methode (die tatsächlich generierte Barcodes innerhalb eines jUnit-Tests decodiert):

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

Ich habe vor kurzem Google Mobile Vision sowohl in iOS als auch in Android verwendet. Ich empfehle dringend, Google Barcode Scan zu verwenden. Es reagiert bei jeder Ausrichtung sehr schnell und die Verarbeitungszeit ist ziemlich schnell. Es heißt Google Mobile Vision.

Die Barcode-Scanner-API erkennt Barcodes in Echtzeit in jeder Ausrichtung. Sie können auch mehrere Barcodes in verschiedenen Formaten gleichzeitig erkennen und analysieren.

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

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


0

Viel einfacher Ansatz.

Fügen Sie einfach die Abhängigkeit in Ihre Gradle-Datei auf App-Ebene ein

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

Definieren Sie eine Schaltfläche in Ihrer XML-Datei und schreiben Sie den folgenden Code in die Java-Datei in OnCreate () und in den OnClick-Listener von button

new IntentIntegrator(this).initiateScan();

Und schreiben Sie den folgenden Code nach OnCreate () der Java-Datei

@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_resultist hier nicht definiert
Kelalaka

Das ist eine globale Variable vom Typ String. Wenn Sie kein gescanntes Ergebnis außerhalb von onActivtyResult () verwenden, können Sie es lokal definieren. Like String st_scanned_result = result.getContents (); Ich habe es plz chk aktualisiert.
Tara

0

2020 UPDATE: Fügen Sie dies einfach Ihrer Gradle-Datei hinzu. Es funktioniert perfekt!

repositories {
   jcenter()
}
implementation 'me.dm7.barcodescanner:zxing:1.9.13'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.