Inconsistent scanning with TC51

// Expert user has replied.
D Dave DiGregorio 3 years 6 months ago
81 3 0

Hi all-
 
We have 3 native Android inventory apps  running on MC40s. Apps were developed using Android Studio 1.5.1 and EMDK 4.0.6. The MC40s are both 4.1 and 4.4.
 
We are now being "encouraged" to begin buying TC51s rather than MC40s. The 3 apps deployed fine to the TC51, They look and work great except the  barcode scanning (in our case code 39) success is inconsistent.  I might get 1 or 2 (at most) successful scans, followed by 5 or so unsuccessful. Eventually pressing the HARD scan button enough times the scan will work. Then it fails again next time. I'd say 10-20% success. onData does not appear to be returning scanData.
 
We are hoping to have a single version of each app work on both the MC40 and TC51.  Should the EMDK 4.0.6 work on the TC51?
 
Is there some scan setting on the TC51 that would help?
 
Our current MC40 code was developed a few years back. Pretty sure we developed it using  "samples" available at that time. Below is the code related to scanning.....
 
 
 
   @Override   protected void onDestroy() {
   super.onDestroy();
  deInitScanner();
   if (barcodeManager != null) {
   barcodeManager = null;
  }
   if (emdkManager != null) {
 
   // Clean up the objects created by EMDK manager   emdkManager.release();
   emdkManager = null;
  }
  }
 
   @Override   protected void onPause() {
   super.onPause();
  deInitScanner();
   if (barcodeManager != null) {
   barcodeManager = null;
  }
   if (emdkManager != null) {
 
   // Clean up the objects created by EMDK manager   emdkManager.release(FEATURE_TYPE.BARCODE);
   emdkManager = null;
  }
  }
 
   @Override   protected void onResume() {
   super.onResume();
   // The application is in foreground  // Acquire the barcode manager resources   if (emdkManager != null) {
   barcodeManager = (BarcodeManager) emdkManager.getInstance(FEATURE_TYPE.BARCODE);
  }
 
 
   @Override   protected void onStop() {
   // TODO Auto-generated method stub   super.onStop();
   // deInitScanner();   try {
   if (scanner != null) {
   // releases the scanner hardware resources for other application  // to use. You must call this as soon as you're done with the  // scanning.   scanner.cancelRead();
   scanner.removeDataListener(this);
   scanner.removeStatusListener(this);
 
   scanner.disable();
   scanner = null;
  }
  } catch (ScannerException e) {
  e.printStackTrace();
  }
  }
 
   @Override   public void onClosed() {
   // TODO Auto-generated method stub   // The EMDK closed abruptly. // Clean up the objects created by EMDK  // manager   if (this.emdkManager != null) {
 
   this.emdkManager.release();
   this.emdkManager = null;
  }
  }
 
   @Override   public void onOpened(EMDKManager emdkManager) {
   // TODO Auto-generated method stub   this.emdkManager = emdkManager;
   // Method call to set some decoder parameters to scanner   setScannerParameters();
   // Get the Barcode Manager object   barcodeManager = (BarcodeManager) this.emdkManager   .getInstance(FEATURE_TYPE.BARCODE);
   // Toast to indicate that the user can now start scanning   Toast.makeText(this,
   "Press Hard Scan Button to start scanning...",
  Toast.LENGTH_SHORT).show();
 
  }
 
 
   @Override   public void onData(ScanDataCollection scanDataCollection) {
   // TODO Auto-generated method stub   // Use the scanned data, process it on background thread using AsyncTask  // and update the UI thread with the scanned results   new AsyncDataUpdate().execute(scanDataCollection);
 
  }
 
   // Update the scan data on UI   int dataLength = 0;
 
   // AsyncTask that configures the scanned data on background  // thread and updated the result on UI thread with scanned data and type of  // label   private class AsyncDataUpdate extends   AsyncTask {
 
   @Override   protected String doInBackground(ScanDataCollection... params) {
 
 
   // Status string that contains both barcode data and type of barcode  // that is being scanned   String statusStr = "";
   try {
   scanner.read();
  ScanDataCollection scanDataCollection = params[0];
 
   // The ScanDataCollection object gives scanning result and the  // collection of ScanData. So check the data and its status   if (scanDataCollection != null   && scanDataCollection.getResult() == ScannerResults.SUCCESS) {
 
  ArrayList scanData = scanDataCollection.getScanData();
 
   // Iterate through scanned data and prepare the statusStr   for (ScanData data : scanData) {
   // Get the scanned data   String barcodeData = data.getData();
   // Get the type of label being scanned   LabelType labelType = data.getLabelType();
   // Concatenate barcode data and label type  // statusStr = barcodeData;   statusStr = barcodeData + " " + labelType;
  }
  }
  } catch (ScannerException e) {
  }
   // Return result to populate on UI thread   return statusStr;
  }
 
   @Override   protected void onPostExecute(String result) {
   // Update the dataView EditText on UI thread with barcode data  // temp debug for tc51 below   Toast.makeText(CountTemplateActivity.this, "Scan before split:" + result,
  Toast.LENGTH_LONG).show();
   //   String[] parts = result.toString().split(" ");
   itemSelected = parts[0];
 
   txt_Item_no.setText(itemSelected);
 
   scannedData = result;
  PARCaptureDB crud = new PARCaptureDB(CountTemplateActivity.this);
 
  Boolean found = crud.getSingleItemForTemplate(templateSelected, itemSelected);
 
   if (found) {
//Code here to check item against SQLite DB and display results
.
.
.
 
  } else {
.
.
.
 
  }
  }
 
   @Override   protected void onPreExecute() {
  }
 
   @Override   protected void onProgressUpdate(Void... values) {
  }
  }
 
   @Override   public void onStatus(StatusData statusData) {
   // TODO Auto-generated method stub   // process the scan status event on the background thread using  // AsyncTask and update the UI thread with current scanner state   new AsyncStatusUpdate().execute(statusData);
  }
 
   // AsyncTask that configures the current state of scanner on background  // thread and updates the result on UI thread   private class AsyncStatusUpdate extends AsyncTask {
 
   @Override   protected String doInBackground(StatusData... params) {
   // Get the current state of scanner in background   StatusData statusData = params[0];
  String statusStr = "";
  ScannerStates state = statusData.getState();
   // Different states of Scanner   switch (state) {
   // Scanner is IDLE   case IDLE:
  statusStr = "The scanner enabled and its idle";
   isScanning = false;
   break;
   // Scanner is SCANNING   case SCANNING:
  statusStr = "Scanning..";
   isScanning = true;
   break;
   // Scanner is waiting for trigger press   case WAITING:
  statusStr = "Waiting for trigger press..";
   break;
   default:
   break;
  }
   // Return result to populate on UI thread   return statusStr;
  }
 
   @Override   protected void onPostExecute(String result) {
   // Update the status text view on UI thread with current scanner  // state   lbl_status_area.setText(result);
  }
 
   @Override   protected void onPreExecute() {
  }
 
   @Override   protected void onProgressUpdate(Void... values) {
  }
  }
 
  
 
   // This is a callback method when user presses any hardware button on the  // device   @Override   public boolean onKeyDown(int keyCode, KeyEvent event) {
 
   // check for scanner hard key press.   if ((keyCode == KeyEvent.KEYCODE_BUTTON_L1)
  || (keyCode == KeyEvent.KEYCODE_BUTTON_R1)) {
 
   // Skip the key press if the repeat count is not zero.   if (event.getRepeatCount() != 0) {
   return true;
  }
 
   try {
   if (scanner == null) {
  initializeScanner();
   // setScannerParameters();   }
 
   if ((scanner != null) && (isScanning == false)) {
   // Starts an asynchronous Scan. The method will not turn on  // the scanner. It will, however, put the scanner in a state  // in which the scanner can be turned ON either by pressing  // a hardware trigger or can be turned ON automatically.   scanner.read();
  }
 
  } catch (Exception e) {
   // Display if there is any exception while performing operation   lbl_status_area.setText(e.getMessage());
  }
   return true;
  }
   return super.onKeyDown(keyCode, event);
  }
 
   // This is a callback method when user releases any hardware button on the  // device   @Override   public boolean onKeyUp(int keyCode, KeyEvent event) {
 
   // check for scanner trigger key press.   if ((keyCode == KeyEvent.KEYCODE_BUTTON_L1)
  || (keyCode == KeyEvent.KEYCODE_BUTTON_R1)) {
 
   // Skip the key press if the repeat count is not zero.   if (event.getRepeatCount() != 0) {
   return true;
  }
 
   try {
   if ((scanner != null) && (isScanning == true)) {
   // This Cancels any pending asynchronous read() calls   scanner.cancelRead();
  }
  } catch (Exception e) {
   lbl_status_area.setText(e.getMessage());
  }
   return true;
  }
   return super.onKeyUp(keyCode, event);
  }
 
   // Method to set some decoder parameters in the ScannerConfig object   public void setScannerParameters() {
   try {
 
   if (scanner == null) {
   // Method call to initialize the scanner parameters   initializeScanner();
  }
 
  ScannerConfig config = scanner.getConfig();
   // Set the code128   config.decoderParams.code128.enabled = true;
   // set code39   config.decoderParams.code39.enabled = true;
   // set UPCA   config.decoderParams.upca.enabled = true;
   scanner.setConfig(config);
 
  } catch (Exception e) {
   lbl_status_area.setText(e.getMessage());
  }
  }
 
   // Method to initialize and enable Scanner and its listeners   private void initializeScanner() throws ScannerException {
   if (barcodeManager == null) {
   try {
 
 
   // Get the Barcode Manager object   barcodeManager = (BarcodeManager) this.emdkManager   .getInstance(FEATURE_TYPE.BARCODE);
 
   // Get default scanner defined on the device   scanner = barcodeManager.getDevice(DeviceIdentifier.INTERNAL_IMAGER1);
   // scanner = barcodeManager.getDevice(list.get(0));   if (scanner != null) {
   // Add data and status listeners   scanner.addDataListener(this);
   scanner.addStatusListener(this);
 
   // The trigger type is set to HARD by default and HARD is not  // implemented in this release.  // So set to SOFT_ALWAYS   scanner.triggerType = TriggerType.HARD;
 
   // Enable the scanner   scanner.enable();
  }
  } catch (Exception e) {
   lbl_status_area.setText("Failed to enable scanner");
  }
  }
  }
 
   private void deInitScanner() {
 
   if (scanner != null) {
 
   try {
 
   scanner.cancelRead();
   scanner.disable();
 
  } catch (Exception e) {
 
   lbl_status_area.setText("Status: " + e.getMessage());
  }
 
   try {
   scanner.removeDataListener(this);
   scanner.removeStatusListener(this);
 
  } catch (Exception e) {
 
   lbl_status_area.setText("Status: " + e.getMessage());
  }
 
   try {
   scanner.release();
  } catch (Exception e) {
 
   lbl_status_area.setText("Status: " + e.getMessage());
  }
 
   scanner = null;
  }
  }
}

Please Register or Login to post a reply

3 Replies

Y Yanis Dalabiras

Hi, you should be submitting the scanner.read() when the scanner is IDLE (see the online sample here: samples-emdkforandroid-6_4/MainActivity.java at BarcodeSample1 · Zebra/samples-emdkforandroid-6_4 · GitHub ).  It looks like you are only submitting the read() in the onKeyDown method.  Read() will enable the hardware trigger to activate the scanning beam, you do not need to listen for the scan key yourself.  I would not recommend using onKeyDown to listen for the hardare trigger for a number of reasons e.g. the labels for the scan keys may be different from device to device (Keymapping Manager - Zebra Technologies Techdocs ) and also you can only trigger a read when the scanner is IDLE.

D Dave DiGregorio

Thanks Darryn and Pietro for your replies.

Reviewing the sample code for BarcodeSample1 and Peter Arcuri's latest DevTalk helped me find an issue. I had scanner.read () in both the onKeyDown and onData. I commented out scanner.read() in onData and scanning now works on both the MC40 and the TC51 with same EMDK 4.0.6 code. Apparently the MC40 didn't have an issue with scanner.read() in both places it has been running that way for a few years now.

Initially I tried to remove onKeyDown as Darryn had suggested but it broke the MC40 scanning.

Thanks again.

P Pietro Francesco Maggi

You can find a good description of the Barcode's Scanner States and when to call the different Scanner's methods in the Barcode Scanning Programmer's Guide:
Barcode Scanning API Programmer's Guide - Zebra Technologies Techdocs

CONTACT
Can’t find what you’re looking for?