B4A Library Wrapper to zxing QRCode, EAN-13 & EAN-8 Generator

Hello group.

This wrapper will allow easy offline creation of QR codes and EAN-13 & EAN-8 barcodes, using the opensource zxing library.

Sample project :
B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim b,b1,b2 As ImageView
   
    Dim qr As QRCode
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
   
    b.Initialize("")
    b1.Initialize("")
    b1.Gravity=Gravity.FILL
    b2.Initialize("")
    b2.Gravity=Gravity.FILL
   
    Activity.AddView(b,0,0,200dip,200dip)
    Activity.AddView(b1,0,220dip,300dip,100dip)
    Activity.AddView(b2,0,330dip,300dip,100dip)
   
    qr.initialize
    b.Bitmap = qr.QR_Encode("TESTING QR CODES",200dip)
    b1.Bitmap = qr.Ean13_Encode(calc_ean_checksum("123456789012"),100dip)
    b2.Bitmap = qr.Ean8_Encode(calc_ean_checksum("1234567"),100dip)
   
   
   
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub calc_ean_checksum(number As String) As String
    Dim i As Int
    Dim c As Char
    Dim soma As Int
    Dim n As Int
    Dim digit As Float
   
    soma = 0
    For i=0 To number.Length - 1
        digit = number.SubString2(i,i+1)
        n= digit * ((i Mod 2) * 2 + 1)   
        soma=soma+n
    Next
    Return number & ( ( 10 - ( soma Mod 10 )) Mod 10 )
End Sub

full wrapper source code, as it's based in a open source project, and someone needs to improve it :

B4X:
package com.inforpires.baQRCode;

import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.*;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DontInheritEvents;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Hide;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.objects.ViewWrapper;
import anywheresoftware.b4a.AbsObjectWrapper;

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;

import android.provider.ContactsContract;

@Version(1.0f)
@Author("Nelson Pires")
@ShortName("QRCode")
@DontInheritEvents
@DependsOn(values={"core-zxing"})

public class baQRCode {

    public void initialize() {
        // WHAT ???
    };
   
    public Bitmap QR_Encode(String qrData,int qrCodeDimention) {

        Bitmap bitmap= Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
       
        QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(qrData, null,
        Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), qrCodeDimention);
        try {
            bitmap = qrCodeEncoder.encodeAsBitmap();
        } catch (WriterException e) {
            e.printStackTrace();
        };
        return bitmap;
    };
   
    public Bitmap Ean13_Encode(String qrData,int qrCodeDimention) {

        Bitmap bitmap= Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
       
        QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(qrData, null,
        Contents.Type.TEXT, BarcodeFormat.EAN_13.toString(), qrCodeDimention);
        try {
            bitmap = qrCodeEncoder.encodeAsBitmap();
        } catch (WriterException e) {
            e.printStackTrace();
        };
        return bitmap;
    };
   
    public Bitmap Ean8_Encode(String qrData,int qrCodeDimention) {

        Bitmap bitmap= Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
       
        QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(qrData, null,
        Contents.Type.TEXT, BarcodeFormat.EAN_8.toString(), qrCodeDimention);
        try {
            bitmap = qrCodeEncoder.encodeAsBitmap();
        } catch (WriterException e) {
            e.printStackTrace();
        };
        return bitmap;
    };
   
   

    private static class Contents {
    private Contents() {
    }

    private 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
    };
}
// -------------------------------------------- Fim
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 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  String trim(String s) {
        if (s == null) { return null; }
        String result = s.trim();
        return result.length() == 0 ? null : result;
    }

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

Decompress the zip to your ExtraLibs folder.

In the zip there is core zxing lib, renamed to zxing-core.jar. This is git pull from 20-08-2013, that i had in my computer. I think that it would be save to get a more recent one, but my home crappy internet would take hours to do a git refresh.

Nelson

Find it usefull ? paypal me a beer. ([email protected])
 

Attachments

  • qrDemo.png
    qrDemo.png
    16.8 KB · Views: 965
  • QRLibs.zip
    383.9 KB · Views: 1,642

urikupfer

Member
Licensed User
Longtime User
vpires
thanks for the library . I have a problem when trying to combine it with ZXingLib(integration version)by icefairy333 (http://www.b4x.com/android/forum/threads/zxinglib-integration-version-by-icefairy333.24233/#content)

I get this error:
Parsing code. 0.11
Compiling code. 1.07
Compiling layouts code. 0.06
Generating R file. 0.70
Compiling generated Java code. 9.30
Convert byte code - optimized dex. Error
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Lcom/google/zxing/ReaderException;
at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
at com.android.dx.command.dexer.Main.processClass(Main.java:490)
at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459)
at com.android.dx.command.dexer.Main.access$400(Main.java:67)
at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398)
at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
at com.android.dx.command.dexer.Main.processOne(Main.java:422)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333)
at com.android.dx.command.dexer.Main.run(Main.java:209)
at com.android.dx.command.dexer.Main.main(Main.java:174)
at com.android.dx.command.Main.main(Main.java:91)
1 error; aborting
Optimized dexer failed. Switching to Standard dexer.

uri
 

urikupfer

Member
Licensed User
Longtime User
hi erel
it is still not working, now i get:
java.lang.NoClassDefFoundError: com.google.zxing.MultiFormatWriter
at com.inforpires.baQRCode.baQRCode$QRCodeEncoder.encodeAsBitmap(baQRCode.java:313)
at com.inforpires.baQRCode.baQRCode.QR_Encode(baQRCode.java:53)
at b4a.example.main._activity_create(main.java:298)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
at b4a.example.main.afterFirstLayout(main.java:98)
at b4a.example.main.access$100(main.java:16)
at b4a.example.main$WaitForLayout.run(main.java:76)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
 

Attachments

  • qr.zip
    1.6 KB · Views: 600

vpires

Member
Licensed User
Longtime User
Hi.
Had a quick look at it. My wrapper uses a newer version of zxing with some differences in the java classes...

Here is a quick & dirty hack that gets scanning & generating codes working together.

*************************************************************************
THIS IS BASED ON THE PUBLISHED SOURCE OF IceFairy333.
If by any chance you don't agree with it, please say so.
*************************************************************************

The sample project, updated with a button to do a scan & generate a QR of the result :

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim b,b1,b2 As ImageView
    Dim bt As Button
   
    Dim qr As QRCode
    Dim sc As Zxing_scanner
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
   
    b.Initialize("")
    b1.Initialize("")
    b1.Gravity=Gravity.FILL
    b2.Initialize("")
    b2.Gravity=Gravity.FILL
   
    Activity.AddView(b,0,0,100dip,100dip)
    Activity.AddView(b1,0,110dip,300dip,100dip)
    Activity.AddView(b2,0,220dip,300dip,100dip)
   
    qr.initialize
    b.Bitmap = qr.QR_Encode("TESTING QR CODES",100dip)
    b1.Bitmap = qr.Ean13_Encode(calc_ean_checksum("123456789012"),100dip)
    b2.Bitmap = qr.Ean8_Encode(calc_ean_checksum("1234567"),100dip)
   
    bt.Initialize("bt")
    bt.Text="SCAN"
    Activity.AddView(bt,0,330dip,100dip,50dip)
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub bt_click
    sc.BeginScan("sc","OJO: Put the code in the small window and have a steady hand")
End Sub
Sub sc_result(atype As String,Values As String)
    Log("Type : " & atype)
    Log("Value : " & Values)
    b.Bitmap = qr.QR_Encode(Values,100dip)
End Sub
Sub sc_noScan
    Log("nothing returned from the scan !!!!!")
End Sub
Sub calc_ean_checksum(number As String) As String
    Dim i As Int
    Dim c As Char
    Dim soma As Int
    Dim n As Int
    Dim digit As Float
   
    soma = 0
    For i=0 To number.Length - 1
        digit = number.SubString2(i,i+1)
        n= digit * ((i Mod 2) * 2 + 1)   
        soma=soma+n
    Next
    Return number & ( ( 10 - ( soma Mod 10 )) Mod 10 )
End Sub

Next we have the published version of IceFairy333 lib with some minor changes :
(Note to the original author : changed package & lib name, hope that's ok with you, if not say so and we will work it out. Just don't beat me with a stick :) )
B4X:
/*
       Based on the original work of IceFairy333

*/
package com.inforpires.barcodescanner;

import android.content.Intent;
import android.util.Log;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Hide;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import anywheresoftware.b4a.IOnActivityResult;
import anywheresoftware.b4a.BA.DependsOn;

import com.google.zxing.client.android.*;


@ShortName("Zxing_scanner")
@Version(1.0F)
@Author("Nelson Pires")
@Events(values={"result(atype as String,Values as String)","noScan"})
@ActivityObject
@Permissions(values={"android.permission.CAMERA","android.permission.WRITE_EXTERNAL_STORAGE","android.hardware.camera","android.hardware.camera.autofocus","android.permission.VIBRATE","android.permission.FLASHLIGHT"})
@DependsOn(values={"core-zxing","zxingscanner"})


public class barcodescanner {
    @Hide
    public static BA myba;
    private IOnActivityResult ion;
    @Hide
    public static String en;
   
public void BeginScan(BA ba,String EventName, String msg) {
    myba=ba;
    en=EventName.toLowerCase();
    Intent izx;
   
   
    izx=new Intent(BA.applicationContext, CaptureActivity.class);
    izx.setAction("com.google.zxing.client.android.SCAN");
    izx.putExtra("PROMPT_MESSAGE",msg);
   
    ion=new IOnActivityResult() {
       
        @Override
        public void ResultArrived(int arg0, Intent arg1) {
            // TODO Auto-generated method stub
            if (arg0==-1){
            String atype;
            String Value;
            atype=arg1.getStringExtra("SCAN_RESULT_FORMAT");
            Value=arg1.getStringExtra("SCAN_RESULT");
            myba.raiseEvent2(null, false, en+"_result", true, new Object[]{atype,Value});
            Log.i("B4A", "Got result code:"+Value);
            }else{
                myba.raiseEvent(null,en+"_noscan");
                Log.i("B4A", "Got other result code:"+arg0);
            }
        }
    };
    ba.startActivityForResult(ion, izx);
}

}

Finally, we have the 20.08.2013 ORIGINAL android version of the zxing app with only the CreateMenu commented out.
(attached)

to use it this way, you need to :

1) add this in the manifest editor
AddApplicationText(<activity android:name="com.google.zxing.client.android.CaptureActivity"
android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden">
</activity>
)
2) decompress res.zip into res folder (inside Objects folder) and set them ReadOnly

3) decompress libs.zip into extralibs of B4A
 

Attachments

  • res.zip
    155.5 KB · Views: 776
  • libs.zip
    126.1 KB · Views: 896

Douglas Farias

Expert
Licensed User
Longtime User
how to save this
b.Bitmap = qr.QR_Encode("TESTING QR CODES",200dip)

to a png or jpg file?
 

vpires

Member
Licensed User
Longtime User
B4X:
Dim oS As OutputStream
oS = File.OpenOutput(File.DirDefaultExternal,"myfile.png",False)
b.WriteToStream(oS,100,"PNG")
 

Douglas Farias

Expert
Licensed User
Longtime User
and the correct way to open a web site when finish scan?

B4X:
Sub sc_result(atype As String,Values As String)
Dim p As PhoneIntents
    ImageView1.Bitmap = qr.QR_Encode(Values,100dip)
    StartActivity(p.OpenBrowser("http://" & Values))
  
End Sub

this is correct?

how can i make to open a site when the code is a url
or open a search google when is a simple text the scan result?
 
Last edited:

juanomoran

Member
Licensed User
Longtime User
Thanks vpires for your library. I have a few questions. I decompressed the lib in the additional libraries folder. I unloaded the old zxing lib and refreshed the project to load new libraries.

I have 2 libs: zxingscan.jar (with its xml file) and zxingscanner.jar alone. What should I do? Replace old b4AZxing.jar lib? What about the "missing" zxingscanner.xml?

None of these two libs load on refresh!!! I think that the xml is corrupt since I can open the zxingscanner.jar outside b4a, but when trying to open the zxingscan.jar, it says that the file is corrupt.

I'm sorry, but I'm a little bit confused with so many similar files being in the additional libs folder

Thanks again
 
Last edited:

chaiwatt

Member
Licensed User
Longtime User
Hi Johan, I have separated post about QR code reader that have no solution yet. I run now on 'NELSON SOLUTION' example and work like a charm. But I have problem that my project require a front camera instead back camera. Is is possible that I can swap to use front camera for the scaning?.
I downloaded some QR code reader app seem they can use both camera (I don't know what they created from which platform). Apologize that I may ark in wrong place, anyway it will be appreciated if you can add this function in next the lib update.
 

Johan Schoeman

Expert
Licensed User
Longtime User
Hi Johan, I have separated post about QR code reader that have no solution yet. I run now on 'NELSON SOLUTION' example and work like a charm. But I have problem that my project require a front camera instead back camera. Is is possible that I can swap to use front camera for the scaning?.
I downloaded some QR code reader app seem they can use both camera (I don't know what they created from which platform). Apologize that I may ark in wrong place, anyway it will be appreciated if you can add this function in next the lib update.


I think you will have to ask the doctors to help you solve this issue and not ask the nurse... Doctors such as Dr Erel and Dr Klaus. :)
 

chaiwatt

Member
Licensed User
Longtime User
Hi Johan, thanks a lot. I like your joke but I beleive that you're expert enought, 55555.
 

Gaver Powers

Member
Licensed User
Longtime User
Hello Johan,

Thanks for your help in producing this library.
Will this code / scanner work without downloading and installing the zxing barcode scanner app from Google Play on the android device?

I tried the version created by IceFairy - there are some differences in the scanning process - my images are distorted (trapezoidal) when viewed by the scanner and there's no target dots (green) being displayed on the qr code in the viewfinder while it's trying to find the corners of the code - like the more recent version of zxing (from google play).

GP
 
Top