Format text in bluetooth printer

I know this is an old thread but it helped me alot so I decided to share my code for simplified use of Formatting.

Sample usage:

final String message = "Example message\n";
// Default format:
writeWithFormat(message.getBytes(), new Formatter().get(), Formatter.leftAlign());
// Bold format center:
writeWithFormat(message.getBytes(), new Formatter().bold().get(), Formatter.centerAlign());
// Bold underlined format with right alignment:
writeWithFormat(message.getBytes(), new Formatter().bold().underlined().get(), Formatter.rightAlign());

Formatter class with Builder pattern:

/**
 * Class for formatting
 */
public static class Formatter {
    /** The format that is being build on */
    private byte[] mFormat;

    public Formatter() {
        // Default:
        mFormat = new byte[]{27, 33, 0};
    }

    /**
     * Method to get the Build result
     *
     * @return the format
     */
    public byte[] get() {
        return mFormat;
    }

    public Formatter bold() {
        // Apply bold:
        mFormat[2] = ((byte) (0x8 | mFormat[2]));
        return this;
    }

    public Formatter small() {
        mFormat[2] = ((byte) (0x1 | mFormat[2]));
        return this;
    }

    public Formatter height() {
        mFormat[2] = ((byte) (0x10 | mFormat[2]));
        return this;
    }

    public Formatter width() {
        mFormat[2] = ((byte) (0x20 | mFormat[2]));
        return this;
    }

    public Formatter underlined() {
        mFormat[2] = ((byte) (0x80 | mFormat[2]));
        return this;
    }

    public static byte[] rightAlign(){
        return new byte[]{0x1B, 'a', 0x02};
    }

    public static byte[] leftAlign(){
        return new byte[]{0x1B, 'a', 0x00};
    }

    public static byte[] centerAlign(){
        return new byte[]{0x1B, 'a', 0x01};
    }
}

The write method that uses the formatting looks like this:

     /**
     * Method to write with a given format
     *
     * @param buffer     the array of bytes to actually write
     * @param pFormat    The format byte array
     * @param pAlignment The alignment byte array
     * @return true on successful write, false otherwise
     */
    public boolean writeWithFormat(byte[] buffer, final byte[] pFormat, final byte[] pAlignment) {
        try {
            // Notify printer it should be printed with given alignment:
            mOutputStream.write(pAlignment);
            // Notify printer it should be printed in the given format:
            mOutputStream.write(pFormat);
            // Write the actual data:
            mOutputStream.write(buffer, 0, buffer.length);

            // Share the sent message back to the UI Activity
            App.getInstance().getHandler().obtainMessage(MESSAGE_WRITE, buffer.length, -1, buffer).sendToTarget();
            return true;
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
            return false;
        }
    }

There are two perceptions to this:

you are just trying to print by passing the text. You are leaving option to the printer to choose to print anyway it wants.

check whether your printer supports Basic Printing Profile[BPP] - Job Based Transfer. I had success printing it in html format, both images and text on a bluetooth printer.

Also, check for the UUID you are providing. They are different UUID for Object push profile, BPP Job Based Transfer profile. I suggest you use the UUID assiged for BPP[Job based transfer] and try passing a xhtml file with formatted text.

Thanks Mani


Now I know how to do it. I had to apply reverse engineering and de-compile an .apk from the market, using dex2jar on Linux and then opening the jar with java de-compiler... Try this...When you write this command:

out.write(str.getBytes(),0,str.getBytes().length);

you are sending to the method a byte[] array. You can modify the format by sending another byte[] array before sending the real byte[] array...

The default format byte[] array is this:

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

So u can try this:

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

out.write(format);

out.write(str.getBytes(),0,str.getBytes().length);

These lines will print the default format text, but if you try below code,

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

format[2] = ((byte)(0x8 | arrayOfByte1[2]));

out.write(format);

out.write(str.getBytes(),0,str.getBytes().length);

it will print text in bold style... You can try these other format arrays:

// Bold
format[2] = ((byte)(0x8 | arrayOfByte1[2]));

// Height
format[2] = ((byte)(0x10 | arrayOfByte1[2]));

// Width
format[2] = ((byte) (0x20 | arrayOfByte1[2]));

// Underline
format[2] = ((byte)(0x80 | arrayOfByte1[2]));

// Small
format[2] = ((byte)(0x1 | arrayOfByte1[2]));

Also you can combine it, then if you like little and bold text, uncomment these array assignments, for example:

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]));
// Underline
// format[2] = ((byte)(0x80 | arrayOfByte1[2]));
// Small
// format[2] = ((byte)(0x1 | arrayOfByte1[2]));
out.write(format);
out.write(str.getBytes(),0,str.getBytes().length);

This last code prints que biggest text size.