androidreact-nativebarcode-scannerdatawedgezebra-scanners

react native datawedge intent zebra scanner taking time to initialize when used on multiple screens


We have a scanner app which has several screens which is having scanner component in it. When initially the app loads on home screen with scanner component, it takes normal time to initialize it, but when we switch from & to the screens the initialization time is increasing 2x from the last one.

Scanner is able to scan the data properly only issue with the initialization time increasing 2x on every screen change.

We are using the zebra et40 device with datawedge version 11.3

We are using "react-native-datawedge-intents": "^0.1.8"

Following is the code of zebra scanner component

import React, { Component } from 'react';
import { DeviceEventEmitter } from 'react-native';
import DataWedgeIntents from 'react-native-datawedge-intents';
import { EventRegister } from 'react-native-event-listeners';

type Props = {
    onScanned: Function,
};
export default class ZebraScanner extends Component<Props, {
    ean8checked: boolean,
    ean13checked: boolean,
    code39checked: boolean,
    code128checked: boolean,
    lastApiVisible: boolean,
    lastApiText: string,
    checkBoxesDisabled: boolean,
    scanButtonVisible: boolean,
    dwVersionText: string,
    activeProfileText: string,
    enumeratedScannersText: string,
    scans: [],
}> {
    sendCommandResult: string;
    broadcastReceiverHandler: (intent: any) => void;

    constructor(props: Props) {
        super(props)
        this.state = {
            ean8checked: true,
            ean13checked: true,
            code39checked: true,
            code128checked: true,
            lastApiVisible: false,
            lastApiText: "Messages from DataWedge will go here",
            checkBoxesDisabled: true,
            scanButtonVisible: false,
            dwVersionText: "Pre 6.3.  Please create and configure profile manually.  See the ReadMe for more details",
            activeProfileText: "Requires DataWedge 6.3+",
            enumeratedScannersText: "Requires DataWedge 6.3+",
            scans: [],
        };
        this.sendCommandResult = "false";
        this.broadcastReceiverHandler = (intent) => {
            this.broadcastReceiver(intent);
        }
        DeviceEventEmitter.addListener('datawedge_broadcast_intent', this.broadcastReceiverHandler);
        this.registerBroadcastReceiver();
        this.determineVersion();
    }

    _onPressScanButton() {
        this.sendCommand("com.symbol.datawedge.api.SOFT_SCAN_TRIGGER", 'TOGGLE_SCANNING');
    }

    determineVersion() {
        this.sendCommand("com.symbol.datawedge.api.GET_VERSION_INFO", "");
    }

    setDecoders() {
        //  Set the new configuration
        var profileConfig = {
            "PROFILE_NAME": "ScannerDemo",
            "PROFILE_ENABLED": "true",
            "CONFIG_MODE": "UPDATE",
            "PLUGIN_CONFIG": {
                "PLUGIN_NAME": "BARCODE",
                "PARAM_LIST": {
                    //"current-device-id": this.selectedScannerId,
                    "scanner_selection": "auto",
                    "decoder_ean8": "" + this.state.ean8checked,
                    "decoder_ean13": "" + this.state.ean13checked,
                    "decoder_code128": "" + this.state.code128checked,
                    "decoder_code39": "" + this.state.code39checked
                }
            }
        };
        this.sendCommand("com.symbol.datawedge.api.SET_CONFIG", profileConfig);
    }

    sendCommand(extraName: string, extraValue: any) {
        const broadcastExtras: any = {};
        broadcastExtras[extraName] = extraValue;
        broadcastExtras["SEND_RESULT"] = this.sendCommandResult;
        DataWedgeIntents.sendBroadcastWithExtras({
            action: "com.symbol.datawedge.api.ACTION",
            extras: broadcastExtras
        });
    }

    registerBroadcastReceiver() {
        DataWedgeIntents.registerBroadcastReceiver({
            filterActions: [
                'com.zebra.reactnativedemo.ACTION',
                'com.symbol.datawedge.api.RESULT_ACTION'
            ],
            filterCategories: [
                'android.intent.category.DEFAULT'
            ]
        });
    }

    broadcastReceiver(intent: any) {
        //  Broadcast received
        if (intent.hasOwnProperty('RESULT_INFO')) {
            const commandResult = intent.RESULT + " (" +
                intent.COMMAND.substring(intent.COMMAND.lastIndexOf('.') + 1, intent.COMMAND.length) + ")";
            this.commandReceived(commandResult.toLowerCase());
        }

        if (intent.hasOwnProperty('com.symbol.datawedge.api.RESULT_GET_VERSION_INFO')) {
            //  The version has been returned (DW 6.3 or higher).  Includes the DW version along with other subsystem versions e.g MX
            const versionInfo = intent['com.symbol.datawedge.api.RESULT_GET_VERSION_INFO'];

            const datawedgeVersion = versionInfo['DATAWEDGE'];

            //  Fire events sequentially so the application can gracefully degrade the functionality available on earlier DW versions
            if (datawedgeVersion >= "11.3")
                this.datawedge113();

            this.setState(this.state);
        } else if (intent.hasOwnProperty('com.symbol.datawedge.api.RESULT_ENUMERATE_SCANNERS')) {
            //  Return from our request to enumerate the available scanners
            const enumeratedScannersObj = intent['com.symbol.datawedge.api.RESULT_ENUMERATE_SCANNERS'];
            this.enumerateScanners(enumeratedScannersObj);
        } else if (intent.hasOwnProperty('com.symbol.datawedge.api.RESULT_GET_ACTIVE_PROFILE')) {
            //  Return from our request to obtain the active profile
            const activeProfileObj = intent['com.symbol.datawedge.api.RESULT_GET_ACTIVE_PROFILE'];
            this.activeProfile(activeProfileObj);
        } else if (!intent.hasOwnProperty('RESULT_INFO')) {
            //  A barcode has been scanned
            this.barcodeScanned(intent, new Date().toLocaleString());
        }
    }

    datawedge113() {
        //  Create a profile for our application
        this.sendCommand("com.symbol.datawedge.api.CREATE_PROFILE", "ScannerDemo");

        this.setState({
            dwVersionText: "11.3",
            checkBoxesDisabled: false
        });

        //  Configure the created profile (associated app and keyboard plugin)
        var profileConfig = {
            "PROFILE_NAME": "ScannerDemo",
            "PROFILE_ENABLED": "true",
            "CONFIG_MODE": "UPDATE",
            "PLUGIN_CONFIG": {
                "PLUGIN_NAME": "BARCODE",
                "RESET_CONFIG": "true",
                "PARAM_LIST": {
                    "configure_all_scanners": 'true',
                    "scanner_input_enabled": 'true',
                    "aim_type": '3',
                    "EXTRA_DATA": {
                        "aim_type": '3',
                    }
                }
            },
            "APP_LIST": [{
                "PACKAGE_NAME": "com.datawedgereactnative.demo",
                "ACTIVITY_LIST": ["*"]
            },
            {
                "PACKAGE_NAME": "com.demo",
                "ACTIVITY_LIST": ["*"]
            }]
        };
        this.sendCommand("com.symbol.datawedge.api.SET_CONFIG", profileConfig);

        //  Configure the created profile (intent plugin)
        var profileConfig2 = {
            "PROFILE_NAME": "ScannerDemo",
            "PROFILE_ENABLED": "true",
            "CONFIG_MODE": "UPDATE",
            "PLUGIN_CONFIG": {
                "PLUGIN_NAME": "INTENT",
                "RESET_CONFIG": "true",
                "PARAM_LIST": {
                    "intent_output_enabled": "true",
                    "intent_action": "com.zebra.reactnativedemo.ACTION",
                    "intent_delivery": "2"
                }
            }
        };
        this.sendCommand("com.symbol.datawedge.api.SET_CONFIG", profileConfig2);
        //  Give some time for the profile to settle then query its value
        setTimeout(() => {
            //  Although we created the profile we can only configure it with DW 6.4.
            this.sendCommand("com.symbol.datawedge.api.GET_ACTIVE_PROFILE", "");

            //  Enumerate the available scanners on the device
            this.sendCommand("com.symbol.datawedge.api.ENUMERATE_SCANNERS", "");

            //  Functionality of the scan button is available
            // this._onPressScanButton();
        }, 1000);
    }

    commandReceived(commandText: string) {
        this.setState(
            {
                lastApiText: commandText
            }
        );
        this.setState(this.state);
    }

    enumerateScanners(enumeratedScanners: any) {
        let humanReadableScannerList: string = "";
        for (let i = 0; i < enumeratedScanners.length; i++) {
            humanReadableScannerList += enumeratedScanners[i].SCANNER_NAME;
            if (i < enumeratedScanners.length - 1)
                humanReadableScannerList += ", ";
        }
        this.setState(
            {
                enumeratedScannersText: humanReadableScannerList,
            }
        )
    }

    activeProfile(theActiveProfile: any) {
        this.setState({
            activeProfileText: theActiveProfile
        });
        this.setState(this.state);
    }

    barcodeScanned(scanData: any, timeOfScan: any) {
        // This is getting called after scanning code each time
        const scannedData = scanData["com.symbol.datawedge.data_string"];
        const scannedType = scanData["com.symbol.datawedge.label_type"];
        EventRegister.emit('barcode_scanned', scannedData);
    }

    render() {
        return (<></>);
    }
}

Following is the code in each of the screens where scanner component used.

import React, { useState } from 'react';

import ZebraScanner from 'components/zebra-scanner';

const ScannerScreen = () => {
  const [scannedText, setScannedText] = useState('No Data Scanned');

  const onScanned = async (scannedData: any) => {
    const scannedCode = scannedData.trim();

    setScannedText(scannedCode);
  }

  return (
    <SafeAreaView style={backgroundStyle}>
      <StatusBar
        barStyle={'dark-content'}
        backgroundColor={backgroundStyle.backgroundColor}
      />
      <ScrollView
        contentInsetAdjustmentBehavior="automatic"
        style={backgroundStyle}>
        <View
          style={{backgroundColor: Colors.white,}}>          
          <ZebraScanner
            onScanned={onScanned}
          />          
          
          <Text style={styles.highlight}>{scannedText}</Text>          
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

export default ScannerScreen;


Solution

  • So I have initialize the zebra component in app.js when app detect the device is zebra.

    {isZebraAvailable ? (<ZebraScanner />) : null}
    

    After that used the context to store the scanned data & used the same scanned data on different screen when required.

    Following is code from zebra scanner where context is used to send data

    const {dispatch,} = getStateContext(); const onScannedData = (data: string) => {
    dispatch({type: 'scannedData',
      scannedData: new String(data),
    });};