HeligPfleigh / react-native-thermal-receipt-printer

A RN library for thermal printer
175 stars 103 forks source link

Java NullPointerException When Connecting to USB Printer #179

Open desmond58 opened 5 months ago

desmond58 commented 5 months ago

The app crashes with a NullPointerException when trying to run any print function like printBill() after connecting a USB device. This happens when the USB device is not a printer.

Errors:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.hardware.usb.UsbDeviceConnection.bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int)' on a null object reference
  com.pinmi.react.printer.adapter.USBPrinterAdapter$2.run(USBPrinterAdapter.java:235)
  java.lang.Thread.run(Thread.java:923)

Init Setup

  useEffect(() => {
    const initializePrinters = async () => {
      try {
        await USBPrinter.init();
        await refreshPrinters(); // Initial loading of printers
        await fetchAndSetSavedPrinters(); // Fetch and set saved printers from the database
      } catch (error) {
        showDialog('Printer Initialization Error', error);
      }
    };
    initializePrinters();
  }, []);

Function to refresh printers (basically get device list): This function will not work if the printer productId is less or equal to 4 digits

const refreshPrinters = async () => {
    try {
      setLoadingPrinters(true);
      // Get the list of USB printers
      const usbPrinterList = await USBPrinter.getDeviceList();
      console.log('USB Printer List:', usbPrinterList);
      // Get the list of Serial devices
      const serialDeviceList = await getUsbDevice();
      // Extract the product IDs of serial devices
      const serialDeviceProductIds = serialDeviceList.map(device => parseInt(device.productId));

      // Filter out USB printers with product IDs greater than 9999 and not a serial devices
      const filteredPrinterList = usbPrinterList.filter(printer => {
        const productId = parseInt(printer.product_id);
        return productId >= 9999 && !serialDeviceProductIds.includes(productId);
      });
      // Set the filtered printer list for both primary and kitchen printers
      setPrimaryPrinter(filteredPrinterList);
      setKitchenPrinter(filteredPrinterList);
      setLoadingPrinters(false);
    } catch (error) {
      setLoadingPrinters(false);
      showSnackbar(`${error}`);
    }
  };

Steps to Reproduce: Select and connect a USB device that is not a printer. Try to print using USBPrinter.printText or USBPrinter.printBill.

How can I prevent the app from crashing when printing with a non-printer USB device? Is there a way to reliably identify and filter out non-printer USB devices before attempting to connect and print?

USB Printer List: [ { "device_id": 2001, "device_name": "/dev/bus/usb/002/001", "product_id": 2, "vendor_id": 7531 }, { "device_id": 3001, "device_name": "/dev/bus/usb/003/001", "product_id": 1, "vendor_id": 7531 }, { "device_id": 5006, "device_name": "/dev/bus/usb/005/006", "product_id": 36907, "vendor_id": 7694 }, { "device_id": 1001, "device_name": "/dev/bus/usb/001/001", "product_id": 2, "vendor_id": 7531 }, { "device_id": 5005, "device_name": "/dev/bus/usb/005/005", "product_id": 4608, "vendor_id": 1504 }, { "device_id": 5001, "device_name": "/dev/bus/usb/005/001", "product_id": 2, "vendor_id": 7531 }, { "device_id": 5004, "device_name": "/dev/bus/usb/005/004", "product_id": 33048, "vendor_id": 4070 }, { "device_id": 5003, "device_name": "/dev/bus/usb/005/003", "product_id": 9492, "vendor_id": 1060 }, { "device_id": 4001, "device_name": "/dev/bus/usb/004/001", "product_id": 1, "vendor_id": 7531 }, { "device_id": 6001, "device_name": "/dev/bus/usb/006/001", "product_id": 3, "vendor_id": 7531 } ]