145 votes

Intégrer la bibliothèque ZXing directement dans mon application Android

J'écris ceci en désespoir de cause :) J'ai été chargé de réaliser un scanner de codes-barres autonome (comme preuve de concept) pour un téléphone Android 1.6.

Pour cela, j'ai découvert la bibliothèque ZXing.

J'ai fait des recherches sur Internet, j'ai lu des sujets connexes ici sur StackOverflow, j'ai fait preuve de bon sens, etc. Rien ne semble avoir aidé, et je n'arrive pas à percer ce blocus mental :/

Je sais qu'il est possible d'utiliser la bibliothèque et de créer son propre scanner de codes-barres autonome. J'ai lu que l'utilisation du "Barcode Scanner" fourni par les gens de Zxing, est de loin la solution la plus facile (via Intent). Malheureusement, ce n'est pas une option, et une application autonome est souhaitée.

Donc, pour résumer mon problème :

  1. Comment intégrer la librairie source de ZXing dans mon projet Android Code via Eclipse ?
  2. Une fois intégré ... comment utiliser la librairie, pour "charger" la fonction de numérisation ?
  3. Un guide étape par étape est préférable car je viens de commencer à travailler avec Eclipse.

J'ai essayé de rendre mon projet de code dépendant du dossier Android du dossier source de ZXing. Lorsque je fais cela, une poignée d'erreurs apparaissent, la plupart concernant 'org.apache' ( ??).

Je n'arrive pas à comprendre... alors quelques conseils seraient les bienvenus.

D'avance, merci :)

0 votes

Je crois que ce que vous vouliez faire se trouve ici : stackoverflow.com/questions/4854442/

0 votes

Le ZXing n'est pas la seule façon de lire un code-barres. Depuis 2016, il est bien plus facile d'utiliser le API code-barres Android .

128voto

AppDev Points 1480

MISE À JOUR ! - RÉSOLU + GUIDE

J'ai réussi à trouver une solution :) En bas de page, vous pouvez lire le guide étape par étape qui, je l'espère, pourra aider d'autres personnes ayant le même problème que moi ;)

  1. Installer Apache Ant - ( Voir cette vidéo YouTube pour une aide à la configuration )
  2. Téléchargez le code source de ZXing depuis la page d'accueil de ZXing et extrayez-le.
  3. En utilisant la ligne de commande de Windows (Run->CMD), naviguez jusqu'au répertoire racine du fichier téléchargé. zxing src .
  4. Dans la fenêtre de la ligne de commande - Tapez ant -f core/build.xml appuyez sur entrée et laissez Apache faire sa magie [ Vous avez des problèmes ? ]
  5. Entrez dans Eclipse -> nouveau projet Android, basé sur le dossier Android dans le répertoire que vous venez d'extraire.
  6. Cliquez avec le bouton droit de la souris sur le dossier du projet -> Propriétés -> Chemin de construction de Java -> Bibliothèque -> Ajouter des JARs externes...
  7. Naviguez vers le dossier nouvellement extrait et ouvrez le répertoire core et sélectionnez core.jar ... appuyez sur la touche Entrée !

Il ne vous reste plus qu'à corriger quelques erreurs dans les traductions et le fichier AndroidManifest.xml :) Maintenant vous pouvez compiler, et vous aurez maintenant une application autonome de scanner de codes barres, basée sur la source ZXing ;)

Bon codage les gars - j'espère que cela peut aider les autres :)

0 votes

Excellent rapport ! Pouvez-vous ajouter quelques détails sur ce que vous avez édité dans la section AndroidManifest.xml fichier ? Après examen, je ne vois pas d'erreur dans ce fichier. Merci !

7 votes

Il n'y a pas d'erreurs dans le fichier AndroidManifest.xml, ni dans les traductions. Il y a cependant des problèmes de compatibilité dans le dernier Android SDK. Si vous l'utilisez, vous devez utiliser un code source plus récent provenant du SVN.

0 votes

Bonjour, j'ai essayé de développer une autre application pour scanner des QR comme une application autonome sans utiliser une application QR Droid ou Barcode Scanner. Est-ce que les étapes que vous avez mentionnées pour faire juste cela ou vous utilisez toujours une autre application via des intents ou autre ?

83voto

Wesam Points 768

Voici un guide étape par étape sur la façon de générer et d'afficher un code QR à l'aide de la bibliothèque ZXing sans avoir à installer l'application tierce. Note : vous n'êtes pas obligé de construire ZXing avec ANT ou tout autre outil de construction. Le fichier core.jar est disponible dans l'archive zip publiée (lire ci-dessous).

  1. Télécharger le dernière version de ZXing . -- ( ZXing-*.zip )
  2. Extrayez cette archive zip et trouvez core.jar en core/ répertoire.
  3. Si vous utilisez l'IDE Eclipse, faites un glisser-déposer. core.jar à la libs de votre projet Android. Lorsqu'on vous le demande, sélectionnez Copie .
  4. Copiez les deux classes données ci-dessous ( Contents.java & QRCodeEncoder.java ) au paquet principal de votre projet Android.
  5. Créer un ImageView dans votre activité pour afficher le code QR généré si vous n'en avez pas déjà un. Un exemple est donné ci-dessous :
  6. Utilisez l'extrait de code ci-dessous pour générer le code QR au format Bitmap et l'afficher dans une fenêtre de dialogue. ImageView .

Voici un ImageView à ajouter à votre fichier XML de présentation des activités :

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

Extraits de code :

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

Voici 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
    };
}

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

La dernière version de ZXing n'a pas de core.jar pour une raison quelconque. J'ai dû télécharger la 2.1 pour l'avoir.

12 votes

Core.jar est disponible séparément dans le dépôt Maven, pour la version 2.2 le lien est le suivant repo1.maven.org/maven2/com/google/zxing/core/2.2/core-2.2.jar

0 votes

Pour tous ceux qui veulent encoder un code EAN (code-barres) au lieu d'utiliser un QR : BarcodeFormat.EAN_13.toString() au lieu de BarcodeFormat.QR_CODE.toString() . Et assurez-vous que votre chaîne contient 13 chiffres. (Ou 8 si vous utilisez EAN_8 au lieu de EAN_13 ). f.e : String qrData = "8718265745940";

11voto

danicolaj Points 91

Des problèmes de construction avec ANT ? Continuez à lire

Si ant -f core/build.xml dit quelque chose comme :

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

puis définissez votre JAVA_HOME dans le dossier java approprié. J'ai trouvé tools.jar dans mon (pour Windows) :

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

donc j'ai mis mon JAVA_HOME à :

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

la raison de la syntaxe plus courte que j'ai trouvée sur un site qui dit :

"Il est fortement conseillé de de choisir un répertoire d'installation qui qui n'inclut pas d'espaces dans le nom (par exemple, n'installez PAS dans le répertoire C:\Program Files). Si Java est installé dans un tel répertoire, il est essentiel de définir l'environnement JAVA_HOME à un chemin d'accès qui ne comporte pas d'espaces (par exemple, le chemin C:\Progra ~1) ; si cela n'est pas fait, cela entraînera la levée d'exceptions par certains programmes qui dépendent de la valeur de JAVA_HOME ".

J'ai ensuite relancé cmd (c'est important car l'interpréteur de commandes DOS ne lit les variables d'environnement qu'au moment du lancement, donc si vous changez une variable d'environnement, vous devrez utiliser un nouvel interpréteur de commandes pour obtenir la valeur mise à jour).

et enfin le ant -f core/build.xml travaillé.

4voto

Scott W Points 6023

Avez-vous vu le pages wiki sur le site web de zxing ? Il semble que vous pourriez trouver Démarrage , Notes du développeur y ScanningViaIntent utile.

0 votes

Désolé ... ce n'était pas vraiment l'aide que je cherchais :) Mais aujourd'hui, j'ai eu une révélation :P J'ai réussi à trouver la solution moi-même ;) Un guide pour les autres utilisateurs ayant le même problème sera bientôt disponible :)

2voto

Siddharth Points 3828

Les gars de zxing ont rendu plus facile la création d'un projet Android avec la version 1.7. Ce n'est plus aussi pénible qu'avant. Il s'agit d'un blog rapide pour tous ceux qui souhaitent créer rapidement un projet zxing pour Android.

  • Vérifiez les sources de zxing sur zxing.org.
  • Créer un projet Android sur votre eclipse
  • Supprimer main.xml
  • Faites un clic droit sur le répertoire "src" et cliquez sur "importer". Naviguez vers les répertoires suivants dans l'ordre mentionné. Lorsque vous les ajoutez un par un pour l'importation, assurez-vous que le répertoire src figure dans le champ d'édition de l'assistant d'importation. Et que vous ne sélectionnez que le répertoire "com" dans l'arborescence de gauche. Ne sélectionnez pas src.
  • noyau dur
  • Intégration d'Android
  • Android
  • Assurez-vous que la version de votre sdk Android est 9, toute version inférieure et androidmanifest.xml pleurera.
  • Strings.xml dans l'une des langues peut être utilisé, il suffit de mettre un / avant le caractère '.

Un projet Android pour zxing 1.7 (vérification du 20 juin).

http://www.4shared.com/file/bFx8Y5Ys/zXingJune2010.html ( N'EST PLUS DISPONIBLE )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X