/*** 保持蓝牙连接的线程*/
public class BluetoothThread extends Thread {// 固定不变,表示蓝牙通用串口服务private static final UUID BLUETOOTH_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");private BluetoothSocket mSocket; // 蓝牙连接的socketprivate OutputStream mOutputStream; // 用于打印数据的输出流private Handler mHandler;private Callback mCallback;private BluetoothDevice mDevice;public BluetoothThread(BluetoothDevice bondedDevice) throws Exception {mDevice = bondedDevice;if (BondState() != BluetoothDevice.BOND_BONDED) {throw new Exception("BluetoothDevice has not bonded.");}try {mSocket = ateRfcommSocketToServiceRecord(BLUETOOTH_UUID); // 创建连接的Socket对象t();mOutputStream = OutputStream();} catch (IOException e) {if (mSocket != null) {try {mSocket.close();} catch (IOException e1) {e1.printStackTrace();}}throw new Exception("BluetoothDevice connect fail. " + e.getMessage());}}public void quit() {if (mHandler == null) {return;}mHandler.sendEmptyMessage(-1);}/*** 发送打印信息(文本或图片 字节码数值格式)* @param bytes*/public void write(byte[] bytes) {if (mHandler == null) {return;}Message msg = mHandler.obtainMessage(0);msg.obj = bytes;mHandler.sendMessage(msg);}public boolean isInnerPrinter() {return "00:11:22:33:44:55".Address());}@SuppressLint("HandlerLeak")@Overridepublic void run() {Looper.prepare();mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == -1) {Looper looper = Looper();if (looper != null) {looper.quit();}removeCallbacksAndMessages(null);mHandler = null;} else {byte[] bytes = (byte[]) msg.obj;try {mOutputStream.write(bytes);if (mCallback != null) {WriteFinished(mDevice);}} catch (IOException e) {if (mCallback != null) {WriteFail(mDevice);}}}}};Looper.loop();// 线程结束,则关闭try {mOutputStream.close();mSocket.close();} catch (IOException e) {e.printStackTrace();}}public void setCallback(Callback callback) {mCallback = callback;}interface Callback {void onWriteFinished(BluetoothDevice device);void onWriteFail(BluetoothDevice device);}
}
/*** 负责蓝牙相关的业务逻辑*/
public class BluetoothManager {private static BluetoothManager sBluetoothManager; // 防止创建多次,设置为单例private static Map<BluetoothDevice, BluetoothThread> mBluetoothThreadMap = new HashMap<>();private int mPrintingThreadCount = 0;private BluetoothManager() {// 通过getInstance()方法获取实例}/*** 获取当前类示例*/public synchronized static BluetoothManager getInstance() {if (sBluetoothManager == null) {sBluetoothManager = new BluetoothManager();}return sBluetoothManager;}/*** 连接蓝牙设备*/public static boolean connect(BluetoothDevice device) {DefaultAdapter().cancelDiscovery();BluetoothThread thread = (device);if (thread == null) {try {thread = new BluetoothThread(device);thread.start();mBluetoothThreadMap.put(device, thread);return true;} catch (Exception e) {e.printStackTrace();return false;}} else {return true;}}private void preparePrint() {int count;do {synchronized (BluetoothManager.class) {count = mPrintingThreadCount;if (count <= 0) {mPrintingThreadCount = mBluetoothThreadMap.size();}}} while (count > 0);}/*** 断开当前正在连接的蓝牙设备*/public void disconnect(BluetoothDevice device) {BluetoothThread thread = (device);if (thread != null) {thread.quit();ve(device);}}/*** 指定某个蓝牙设备打印文本内容** @param text 打印的文本内容*/public void printText(BluetoothDevice device, String text, final OnPrintListener listener) {if (TextUtils.isEmpty(text)) {return;}byte[] bytes = new byte[0];try {bytes = Bytes("GBK");} catch (UnsupportedEncodingException e) {e.printStackTrace();}addListenerAndPrint(device,bytes,listener);}/*** 指定某个蓝牙设备打印图片* @param device* @param bitmap*/public void printBitmap(BluetoothDevice device, Bitmap bitmap, final OnPrintListener listener) {if (null==bitmap) {return;}byte[] bit = PrintUtil.draw2PxPoint(bitmap);addListenerAndPrint(device,bit,listener);}private void addListenerAndPrint(BluetoothDevice device,byte[] bit,final OnPrintListener listener){final BluetoothThread thread = (device);if (thread == null) {throw new RuntimeException("蓝牙连接不存在!");}if (listener != null) {thread.setCallback(new BluetoothThread.Callback() {@Overridepublic void onWriteFinished(BluetoothDevice device) {thread.setCallback(null);PrintFinished();}@Overridepublic void onWriteFail(BluetoothDevice device) {thread.setCallback(null);PrintFail(device);}});}thread.write(bit);}public interface OnPrintListener {void onPrintFinished();void onPrintFail(BluetoothDevice device);}
}
public class PrintUtil {/*** 对图片进行压缩(去除透明度)** @param bitmap*/public static Bitmap compressPic(Bitmap bitmap) {// 获取这个图片的宽和高int width = Width();int height = Height();// 指定调整后的宽度和高度int newWidth = 240;int newHeight = 240;Bitmap targetBmp = ateBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);Canvas targetCanvas = new Canvas(targetBmp);targetCanvas.drawColor(0xffffffff);targetCanvas.drawBitmap(bitmap, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);return targetBmp;}/************************************************************************** 假设一个240*240的图片,分辨率设为24, 共分10行打印* 每一行,是一个 240*24 的点阵, 每一列有24个点,存储在3个byte里面。* 每个byte存储8个像素点信息。因为只有黑白两色,所以对应为1的位是黑色,对应为0的位是白色**************************************************************************//*** 把一张Bitmap图片转化为打印机可以打印的字节流** @param bmp* @return*/public static byte[] draw2PxPoint(Bitmap bmp) {
// bmp = compressPic(bmp);//用来存储转换后的 bitmap 数据。为什么要再加1000,这是为了应对当图片高度无法//整除24时的情况。比如bitmap 分辨率为 240 * 250,占用 7500 byte,//但是实际上要存储11行数据,每一行需要 24 * 240 / 8 =720byte 的空间。再加上一些指令存储的开销,//所以多申请 1000byte 的空间是稳妥的,不然运行时会抛出数组访问越界的异常。int size = Width() * Height() / 8 + 5000;byte[] data = new byte[size];int k = 0;//设置行距为0的指令data[k++] = 0x1B;data[k++] = 0x33;data[k++] = 0x00;// 逐行打印for (int j = 0; j < Height() / 24f; j++) {//打印图片的指令data[k++] = 0x1B;data[k++] = 0x2A;data[k++] = 33;data[k++] = (byte) (Width() % 256); //nLdata[k++] = (byte) (Width() / 256); //nH//对于每一行,逐列打印for (int i = 0; i < Width(); i++) {//每一列24个像素点,分为3个字节存储for (int m = 0; m < 3; m++) {//每个字节表示8个像素点,0表示白色,1表示黑色for (int n = 0; n < 8; n++) {byte b = px2Byte(i, j * 24 + m * 8 + n, bmp);data[k] += data[k] + b;}k++;}}data[k++] = 10;//换行}return data;}/*** 灰度图片黑白化,黑色是1,白色是0** @param x 横坐标* @param y 纵坐标* @param bit 位图* @return*/public static byte px2Byte(int x, int y, Bitmap bit) {if (x < Width() && y < Height()) {byte b;int pixel = Pixel(x, y);int red = (pixel & 0x00ff0000) >> 16; // 取高两位int green = (pixel & 0x0000ff00) >> 8; // 取中两位int blue = pixel & 0x000000ff; // 取低两位int gray = RGB2Gray(red, green, blue);if (gray < 128) {b = 1;} else {b = 0;}return b;}return 0;}/*** 图片灰度的转化*/private static int RGB2Gray(int r, int g, int b) {int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b); //灰度转化公式return gray;}
}
代码整合了诸多大佬的博客,非原创。
本文发布于:2024-01-31 08:51:27,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170666229027322.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |