Razgriz
Razgriz

Reputation: 7343

Android - Bluetooth Printer not finished printing but throws IOException: Socket Closed

I have an application that prints data (text and image) to a thermal printer.

My problem is that whenever I print lengthy data, the printout gets cut and and I get an IOException: Socket Closed thrown in the try catch statement where I print.

Here is the part where I print my data:

protected void simpleComm(Integer port){
    //InputStream tmpIn = null;
    byte[] buffer = new byte[3]; //{65,65,53,53,49,52,65,66,67,68};

    buffer[0] = (byte) 0x08;
    buffer[1] = (byte) 0x99;
    buffer[2] = (byte) 0x04;
    OutputStream tmpOut;// = null;    

    bluetoothAdapter.cancelDiscovery();

    Log.d(this.toString(), "Port = " + port);
    try {


        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        Method m = blueToothDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
        socket = (BluetoothSocket) m.invoke(blueToothDevice, port);

        //socket = mmDevice.createRfcommSocketToServiceRecord(uuid);

        // assert (socket != null) : "Socket is Null";
        socket.connect();

        try {
            Log.d(this.toString(),"************ CONNECTION SUCCEES! *************");
            try{
                //tmpIn=socket.getInputStream();
                tmpOut = socket.getOutputStream();

                //mmInStream = tmpIn;
                mmOutStream = tmpOut;

            }
            catch(Exception ex){
                Log.e(this.toString(), "Exception " + ex.getMessage());
            }

            //TODO print sequence starts here

            image = "logo";
            print_image(Environment.getExternalStorageDirectory().toString() + "/LOGO.png");

            byte[] arrayOfByte1 = { 27, 33, 0 };
            byte[] format = { 27, 33, 0 };

            mmOutStream.write((newline).getBytes("US-ASCII"));


            //bold
            format[2] = ((byte)(0x0 | arrayOfByte1[2]));  
            //width
            format[2] = ((byte)(0x12 | arrayOfByte1[2]));
            //height
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));
            mmOutStream.write(format);


            for(int i = 0 ; i < orderListForPrinting.size(); i++ ){
                mmOutStream.write(((List.get(i)).getBytes("US-ASCII")));
            }


            //bold
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));  
            //width
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));
            //height
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));
            mmOutStream.write(format);

            mmOutStream.write((newline).getBytes("US-ASCII"));


            printSignature();

            //bold
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));  
            //width
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));
            //height
            format[2] = ((byte)(0x8 | arrayOfByte1[2]));
            mmOutStream.write(format);

            mmOutStream.write(( name + "                  " + newline + newline).getBytes("US-ASCII"));                

        }
        finally{

            orderList = new ArrayList<TotalOrderClass>();
            orderListForPrinting = new ArrayList<String>();
            socket.close();
            mmOutStream.flush();
        }
    } 
    catch (IOException ex){
        Log.e(this.toString(), "IOException: " + ex.getMessage());
    } 
    catch (NoSuchMethodException ex){
        Log.e(this.toString(), "NoSuchMethodException: " + ex.getMessage());
    } 
    catch (IllegalAccessException ex){
        Log.e(this.toString(), "IllegalAccessException: " + ex.getMessage());
    } 
    catch (InvocationTargetException ex){
        Log.e(this.toString(),"InvocationTargetException: " + ex.getMessage());
    }

}

Here is my print Signature function, which is similar to the function I use to print the logo.

private void printSignature() {
    //TODO print signature here
    convertBitmap(signature);
    try{
        mmOutStream.write(PrinterCommands.SET_LINE_SPACING_24);

        int offset = 0;
        while (offset < signature.getHeight()) {
            mmOutStream.write(PrinterCommands.SELECT_BIT_IMAGE_MODE_SIGNATURE);
            for (int x = 0; x < signature.getWidth(); ++x) {

                for (int k = 0; k < 3; ++k) {

                    byte slice = 0;
                    for (int b = 0; b < 8; ++b) {
                        int y = (((offset / 8) + k) * 8) + b;
                        int i = (y * signature.getWidth()) + x;
                        boolean v = false;
                        if (i < dots.length()) {
                            v = dots.get(i);
                        }
                        slice |= (byte) ((v ? 1 : 0) << (7 - b));
                    }
                    mmOutStream.write(slice);
                }
            }
            offset += 24;
            mmOutStream.write(PrinterCommands.FEED_LINE);
        }

        mmOutStream.write(PrinterCommands.SET_LINE_SPACING_30);
    }
    catch (IOException e) {
        Toast.makeText(getApplicationContext(), "Catch on to print signature stuff", Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }

}

ConvertBitmap function:

public String convertBitmap(Bitmap inputBitmap) {

    int mWidth = inputBitmap.getWidth();
    int mHeight = inputBitmap.getHeight();

    convertArgbToGrayscale(inputBitmap, mWidth, mHeight);
    String mStatus = "ok";
    return mStatus;

}

convertArgbToGrayScale function:

private void convertArgbToGrayscale(Bitmap bmpOriginal, int width,
        int height) {
    int pixel;
    int k = 0;
    int B = 0, G = 0, R = 0;
    dots = new BitSet();
    try {

        for (int x = 0; x < height; x++) {
            for (int y = 0; y < width; y++) {
                // get one pixel color
                pixel = bmpOriginal.getPixel(y, x);

                // retrieve color of all channels
                R = Color.red(pixel);
                G = Color.green(pixel);
                B = Color.blue(pixel);
                // take conversion up to one single value by calculating
                // pixel intensity.
                R = G = B = (int) (0.299 * R + 0.587 * G + 0.114 * B);
                // set bit into bitset, by calculating the pixel's luma
                if (R < 55) {                       
                    dots.set(k);//this is the bitset that i'm printing
                }
                k++;

            }


        }


    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), "Catch on to Grayscale stuff", Toast.LENGTH_LONG).show();
    }
}

My issue right now is that after calling the printSignature() function, the printer stops printing and the socket is closed, which is why I am getting the IOException: Socket Closed error.

I've run through this functions a handful of times and I don't know why the socket is closing since I only close the socket at the finally clause of the try-catch.

Any ideas?

Upvotes: 0

Views: 2735

Answers (2)

webnator
webnator

Reputation: 13

What I do, is that I put a Thread.sleep(x), after every .Write(), where x, is the amount of characters in my output string, that can differ in your code, but the amount of waiting that the program has to do before closing, is proportional, to the amount of chars (or lines) printing.

Upvotes: 0

Skaard-Solo
Skaard-Solo

Reputation: 682

What happpend if you put a Thread.sleep(2000) right before the socket.close()?

I work on bluetooth SPP and I had the same issue (Socket close before the end of data transfer). I think that the broadcast of socket.close() is faster than the transmission of the data, then all the data are not analyze by the BT printer when the close request is send

Upvotes: 2

Related Questions