1

Hello I am new to android I have spent so much time on trying to print a receipt in my app. I use a Zicox XT4131 thermal printer which connects via bluetooth to my tablet running the Android 4.4 OS.

SO far I have successfully been able to print only text on my receipt, now my next hurdle is trying to print barcodes, qrcodes and logos on my receipt, I have spent many hours on the internet trying to find a solution for this but nothing seems to work.

What I have learned however is that to print a bitmap image, i first need to convert it to a byte array (which I did) and write it to the output stream (which I also did), all I got after that was either a long blank space on the printer or some weird characters.

Right now I'm refusing to believe in 2016 printing from a tablet to a printer has no simple solution so I only assume I am going about all this the wrong way.

The way my app works is simple, in my activity where I have a preview of the purchase there is a button which upon being clicked sends a command to the bluetooth printer to print. That is all, no converting to pdf and what not and having to select a printer.

So what I would like to know is what exactly is the way for me to correctly print a receipt from my tablet to my bluetooth printer and how exactly would I use such method to print a barcode, qrcode or logo along with the text on the receipt?

I do not want this to be voted as off topic as that may require me abandon this project (all because of printing) I just want one workable efficient solution that can help me do what I want to do.

This is my code for printing right now:

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Handler;
import android.view.View;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.nio.ByteBuffer;

import java.util.EnumMap;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

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;

These are the functions for it:

// this will find a bluetooth printer device
void findBT() {

    try {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if(mBluetoothAdapter == null) {
            Toast.makeText(PurchaseSummaryActivity.this, "No bluetooth adapter available", Toast.LENGTH_SHORT).show();
        }

        if(!mBluetoothAdapter.isEnabled()) {
            Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetooth, 0);
        }

        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

        if(pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {

                // RPP300 is the name of the bluetooth printer device
                // we got this name from the list of paired devices
                if (device.getName().equals("XT4131A")) {
                    mDevice = device;
                    break;
                }
            }
        }

        Toast.makeText(PurchaseSummaryActivity.this, "Bluetooth device found.", Toast.LENGTH_SHORT).show();

    }catch(Exception e){
        e.printStackTrace();
    }
}

// tries to open a connection to the bluetooth printer device
void openBT() throws IOException {
    try {

        // Standard SerialPortService ID
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
        mSocket = mDevice.createRfcommSocketToServiceRecord(uuid);
        mSocket.connect();
        mOutputStream = mSocket.getOutputStream();
        mInputStream = mSocket.getInputStream();

        beginListenForData();

        Toast.makeText(PurchaseSummaryActivity.this, "Bluetooth Connection Opened", Toast.LENGTH_SHORT).show();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

/*
 * after opening a connection to bluetooth printer device,
 * we have to listen and check if a data were sent to be printed.
 */
void beginListenForData() {
    try {
        final Handler handler = new Handler();

        // this is the ASCII code for a newline character
        final byte delimiter = 10;

        stopWorker = false;
        readBufferPosition = 0;
        readBuffer = new byte[1024];

        workerThread = new Thread(new Runnable() {
            public void run() {

                while (!Thread.currentThread().isInterrupted() && !stopWorker) {

                    try {

                        int bytesAvailable = mInputStream.available();

                        if (bytesAvailable > 0) {

                            byte[] packetBytes = new byte[bytesAvailable];
                            mInputStream.read(packetBytes);

                            for (int i = 0; i < bytesAvailable; i++) {

                                byte b = packetBytes[i];
                                if (b == delimiter) {

                                    byte[] encodedBytes = new byte[readBufferPosition];
                                    System.arraycopy(
                                            readBuffer, 0,
                                            encodedBytes, 0,
                                            encodedBytes.length
                                    );

                                    // specify US-ASCII encoding
                                    final String data = new String(encodedBytes, "US-ASCII");
                                    readBufferPosition = 0;

                                    // tell the user data were sent to bluetooth printer device
                                    handler.post(new Runnable() {
                                        public void run() {
                                            Toast.makeText(PurchaseSummaryActivity.this, data, Toast.LENGTH_SHORT).show();
                                        }
                                    });

                                } else {
                                    readBuffer[readBufferPosition++] = b;
                                }
                            }
                        }

                    } catch (IOException ex) {
                        stopWorker = true;
                    }

                }
            }
        });

        workerThread.start();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

// this will send text data to be printed by the bluetooth printer
void printTickets(Event eo, Cart.Ticket to) throws IOException {
    try {
        byte[] arrayOfByte1 = { 27, 33, 0 };
        byte[] format = { 27, 33, 0 };
        // Bold
        format[2] = ((byte)(0x8 | arrayOfByte1[2]));
        // Height
        format[2] = ((byte)(0x10 | arrayOfByte1[2]));
        // Width
        format[2] = ((byte) (0x20 | arrayOfByte1[2]));
        byte[] center = new byte[]{ 0x1b, 0x61, 0x01 };
        // the text typed by the user
        StringBuilder msg = new StringBuilder();
        msg.append("\n");
        msg.append("\n");
        msg.append("\n myTicketGH");
        mOutputStream.write(center);
        mOutputStream.write(format);
        mOutputStream.write(msg.toString().getBytes());

        // Bold
        format[2] = ((byte)(0x8 | arrayOfByte1[2]));
        msg = new StringBuilder();
        msg.append("\n Address: No 10, Otublohum street");
        msg.append("\n North Industrial Area");
        msg.append("\n Tel.: 0266 8888 64");
        msg.append("\n");
        msg.append("\n");
        msg.append("\n");
        mOutputStream.write(center);
        mOutputStream.write(format);
        mOutputStream.write(msg.toString().getBytes());

        // Bold
        format[2] = ((byte)(0x8 | arrayOfByte1[2]));
        byte[] left = new byte[]{ 0x1b, 0x61, 0x00 };
        msg = new StringBuilder();
        msg.append("\n Event");
        mOutputStream.write(format);
        mOutputStream.write(left);
        mOutputStream.write(msg.toString().getBytes());

        mOutputStream.write(arrayOfByte1);

        left = new byte[]{ 0x1b, 0x61, 0x00 };
        msg = new StringBuilder();
        msg.append("\n  Name  : " + eo.getName());
        msg.append("\n  Date  : " + eo.getDate());
        msg.append("\n  Time  : " + eo.getTime());
        msg.append("\n  Venue : " + eo.getVenue());
        msg.append("\n");
        msg.append("\n");
        mOutputStream.write(arrayOfByte1);
        mOutputStream.write(left);
        mOutputStream.write(msg.toString().getBytes());

        // Bold
        format[2] = ((byte)(0x8 | arrayOfByte1[2]));
        msg = new StringBuilder();
        msg.append("\n Ticket");
        mOutputStream.write(format);
        mOutputStream.write(left);
        mOutputStream.write(msg.toString().getBytes());

        mOutputStream.write(arrayOfByte1);

        left = new byte[]{ 0x1b, 0x61, 0x00 };
        msg = new StringBuilder();
        msg.append("\n  Code              : " + to.getCode());
        msg.append("\n  Class             : " + to.getTclass() );
        msg.append("\n  Fee               : " + to.getPrice());
        msg.append("\n  Seat              : " + "N / A");
        msg.append("\n  Date of Purchase  : " + Calendar.getInstance().getTime().toString());
        msg.append("\n");
        msg.append("\n");
        msg.append("\n");
        msg.append("\n");
        msg.append("\n");
        mOutputStream.write(arrayOfByte1);
        mOutputStream.write(left);
        mOutputStream.write(msg.toString().getBytes());

        // barcode data
        String barcode_data = "123456";

        // barcode image
        byte[] barCodeBytes;
        String barCodeHex = "";

        try {
            barCode = encodeAsBitmap(barcode_data, BarcodeFormat.CODE_128, 300, 40);
            barCode = bitmapToGrayscale(barCode);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            barCodeBytes = stream.toByteArray();
            mOutputStream.write(barCodeBytes);


        } catch (WriterException e) {
             e.printStackTrace();
        }



    } catch (Exception e) {
        e.printStackTrace();
    }
}

// close the connection to bluetooth printer.
void closeBT() throws IOException {
    try {
        stopWorker = true;
        mOutputStream.close();
        mInputStream.close();
        mSocket.close();
        // myLabel.setText("Bluetooth Closed");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

This is my onClickEvent handler:

this.buttonNextView.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        try {
            findBT();
            openBT();

            for (int i = 0; i < ta.length(); i++)
            {
                try {
                    printTickets(eo, new Cart(). new Ticket(
                            ta.getJSONObject(i).getInt("id"),
                            ta.getJSONObject(i).getString("code"),
                            ta.getJSONObject(i).getString("class"),
                            ta.getJSONObject(i).getString("description"),
                            Float.parseFloat(ta.getJSONObject(i).getString("price")),
                            ta.getJSONObject(i).getInt("quantity")

                    ));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            closeBT();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
});

And yes the printer I use is capable of printing barcodes and qr codes.

user3718908x100
  • 7,939
  • 15
  • 64
  • 123
  • How are you printing barcodes/QR codes if your code isn't working? May help to read: http://stackoverflow.com/questions/14530058/how-can-i-print-an-image-on-a-bluetooth-printer-in-android – Morrison Chang Apr 09 '16 at 02:07
  • I am not, that's my reason for this post, I stated that I can only print text and that when I try to print a barcode, qrcode or logo it doesn't work. – user3718908x100 Apr 09 '16 at 07:45
  • All that solution does is print question marks on my receipt. – user3718908x100 Apr 09 '16 at 23:18
  • I have no idea what is happening and I can't seem to find any working solution online or any answers here. :( – user3718908x100 Apr 09 '16 at 23:28
  • You have to figure out what your printer is compatible with. If you can find a Windows driver that may provide clues. Alternatively your printer may support the other protocols like PCL or ZPL that my link lists out and you'll have to try one by one. Best would be a manufacturer website/document which lists support modes (i.e. how to enable EPL o ESC). Unfortunately all I can find is: http://zicox.en.alibaba.com/product/2017320351-222721720/portable_mobile_printer_supports_the_EPL_ZPL_ESC_SDK_XT4131A_.html. Good luck. – Morrison Chang Apr 10 '16 at 01:29
  • Okay but what I would basically like to know before even talking about the barcode system to use is the code, am I doing it the right way? – user3718908x100 Apr 10 '16 at 01:31

0 Answers0