Razgriz
Razgriz

Reputation: 7343

Bluetooth printing throws an IOException from the Socket across different devices

I am trying to print to a thermal printer via Bluetooth.

I was able to successfully print before on a Nexus 7 Device (both the first and second generations). However, when I copy pasted the exact same code on a different application and deployed it on an Asus Tablet, I suddenly got an IOException that tells me that my socket might be closed.

Here is my code:

public void onPrintReceipt(){

    Toast.makeText(getApplicationContext(), "Printing", Toast.LENGTH_LONG).show();

    try{
        Set<BluetoothDevice> bdevices = bluetoothAdapter.getBondedDevices();
        blueToothDevice = bluetoothAdapter.getRemoteDevice("00:01:90:EE:B2:52");

        simpleComm(1);
    }
    catch(Exception ex){
        Log.e("", "simpleComm() Catch Statement Entered");
    }
}


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.e(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);

        // assert (socket != null) : "Socket is Null";
        if(socket.isConnected()){
            socket.close();
        }
        socket.connect();

        try {

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

                //mmInStream = tmpIn;
                mmOutStream = tmpOut;
                out = new BufferedWriter(new OutputStreamWriter(mmOutStream));

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

            //TODO print sequence starts here

            //....snip snip a LOT of code

        }
        finally{

            mmOutStream.flush();

            mmOutStream.close();
            socket.close();

        }

    }
    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());
    }

}

And here is the error from the try-catch block:

IOException: read failed, socket might closed or timeout, read ret: -1

And now I am confused as to why there's suddenly an error when all I did was to deploy the code on a different device.

How can I proceed?

Upvotes: 0

Views: 1056

Answers (1)

hgross
hgross

Reputation: 690

I see you use reflection to create your RFCOMM connection. This is pretty dangerous, I recently answered a question in that regard: How do Bluetooth SDP and UUIDs work? (specifically for Android)

Tl;dr: You are bypassing the SDP lookup mechanism that maps an UUID to an appropriate Bluetooth channel on the device you connect to. Your code ALWAYS connects to bluetooth channel 1. That might work initially/some cases - but could also be your problem. It depends on the receiving device.

You are creating an UUID. I guess (hope) you have it from the printer's documentation? But if you check your code, you will see that you are not using it to connect to the printer - which you absolutely should do (refer to the linked answer, for the whole story). Use createRfcommSocketToServiceRecord(uuid) to open your socket.

Since you are using the Nexus 7: I used two Nexus 7, a Nexus 4 and 10 other devices to test a bluetooth middleware for android I wrote. Especially the Nexus devices were pretty sensitive when the bluetooth was stressed by many concurrent calls leading to a completely useless bluetooth adapter until I power cycled them. Additionally I think to remember there was a bug in cases when I used this hacky reflection snippet that filled up the bt-adapter's channels until no one was left resulting in total bluetooth failure (I wasn't able to find the link to the related official android bug report, but there is one for the Nexus devices).

Upvotes: 1

Related Questions