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?