0

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Razgriz
  • 7,179
  • 17
  • 78
  • 150
  • *"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."* because coding for BT sucks. It can be different between different devices/models/versions. But what happens in `connect()`? It seems that something there isn't executing properly. – codeMagic Jun 16 '15 at 00:34
  • @codeMagic it would seem that that is the case. I just ran the exact same code I'm trying on run on my Acer Tablet to my Nexus 7 units. The Nexus 7 units had no problem printing to the thermal printer via bluetooth. Looks like some lower level interaction is at hand. – Razgriz Jun 16 '15 at 01:17
  • [Tell me](http://stackoverflow.com/questions/25651586/bluetooth-not-connecting-on-4-4-2) about it....[Bt is fun!](http://stackoverflow.com/questions/15341445/ioexception-on-accept-thread). But it still seems like it has to do with your `connect()` method. Maybe something in there can be altered to make it work. – codeMagic Jun 16 '15 at 01:22

1 Answers1

1

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).

Community
  • 1
  • 1
hgross
  • 690
  • 6
  • 15