Integrating the ZXing library directly into my Android application

后端 未结 17 1418
[愿得一人]
[愿得一人] 2020-11-22 04:35

I\'m writing this in mere desperation :) I\'ve been assigned to make a standalone barcode scanner (as a proof of concept) to an Android 1.6 phone.

For this i\'ve dis

相关标签:
17条回答
  • 2020-11-22 05:26

    I tried all possible ways to achieve this and then I discovered Minified version of xZing by JourneyApps. I have ported that for eclipse and shared on GitHub.

    If you are using eclipse use this project:-

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

    If you are using Studio use this project :-

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

    Advantages

    1. Inbuilt Barcode scanner in your App do not required to install third party apps using playstore.

    2. You dont need to get confused between Core,Android client etc jars simply drop this packages and relevent layouts in your project and you are good to go. Only Jar required is com.google.zxing:core:3.2.0 which you can download from

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

    3. No need to add tons of packages see images below for comparison

    Before :-

    After :-

    1. Most important part is they are highly customizable ie. you can add flash light, use it in fragment and support orientation change.

    2. You can use this Capture activity in Cordova App for barcode scanneing.

    your capture activity in app manifest would look like this

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

    and plugin will look like this

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

    Happy Integration !!

    0 讨论(0)
  • 2020-11-22 05:27

    Why use an external lib, when google play services (since version 7.8.0) includes a barcode decoder.

    0 讨论(0)
  • 2020-11-22 05:30

    This library works like a charm, easy to integrate and use. https://github.com/dm77/barcodescanner

    0 讨论(0)
  • 2020-11-22 05:31

    I just wrote a method, which decodes generated bar-codes, Bitmap to String.

    It does exactly what is being requested, just without the CaptureActivity...

    Therefore, one can skip the android-integration library in the 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')
    }
    

    The method as following (which actually decodes generated bar-codes, within a jUnit test):

    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 讨论(0)
  • 2020-11-22 05:31

    2020 UPDATE: Just add this to your Gradle file. It works perfectly!

    repositories {
       jcenter()
    }
    implementation 'me.dm7.barcodescanner:zxing:1.9.13'
    
    0 讨论(0)
提交回复
热议问题