android 佳博蓝牙打印机功能开发
生活随笔
收集整理的這篇文章主要介紹了
android 佳博蓝牙打印机功能开发
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
藍牙自動連接已配對設備
private void connectBluetooth(){BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();if (pairedDevices.size()!=0){for (BluetoothDevice device : pairedDevices) {connect(device.getAddress());}}else {Toasts.show("暫無配對設備");}}根據(jù)藍牙地址,初始化線程池去做連接操作
private void connect(String address){//初始化話DeviceConnFactoryManagerdeviceConnFactoryManager=new DeviceConnFactoryManager.Build().setId(0)//設置連接方式.setConnMethod(DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH)//設置連接的藍牙m(xù)ac地址.setMacAddress(address).build();//打開端口ThreadPool.getInstantiation().addTask(new Runnable() {@Overridepublic void run() {DeviceConnFactoryManager.getDeviceConnFactoryManagers()[0].openPort();}});}DeviceConnFactoryManager.java
public class DeviceConnFactoryManager {public PortManager mPort;private static final String TAG = DeviceConnFactoryManager.class.getSimpleName();public CONN_METHOD connMethod;private String ip;private int port;private String macAddress;private UsbDevice mUsbDevice;private Context mContext;private String serialPortPath;private int baudrate;private int id;private static DeviceConnFactoryManager[] deviceConnFactoryManagers = new DeviceConnFactoryManager[4];private boolean isOpenPort;/*** ESC查詢打印機實時狀態(tài)指令*/private byte[] esc = {0x10, 0x04, 0x02};/*** ESC查詢打印機實時狀態(tài) 缺紙狀態(tài)*/private static final int ESC_STATE_PAPER_ERR = 0x20;/*** ESC指令查詢打印機實時狀態(tài) 打印機開蓋狀態(tài)*/private static final int ESC_STATE_COVER_OPEN = 0x04;/*** ESC指令查詢打印機實時狀態(tài) 打印機報錯狀態(tài)*/private static final int ESC_STATE_ERR_OCCURS = 0x40;/*** TSC查詢打印機狀態(tài)指令*/private byte[] tsc = {0x1b, '!', '?'};/*** TSC指令查詢打印機實時狀態(tài) 打印機缺紙狀態(tài)*/private static final int TSC_STATE_PAPER_ERR = 0x04;/*** TSC指令查詢打印機實時狀態(tài) 打印機開蓋狀態(tài)*/private static final int TSC_STATE_COVER_OPEN = 0x01;/*** TSC指令查詢打印機實時狀態(tài) 打印機出錯狀態(tài)*/private static final int TSC_STATE_ERR_OCCURS = 0x80;private byte[] cpcl={0x1b,0x68};/*** CPCL指令查詢打印機實時狀態(tài) 打印機缺紙狀態(tài)*/private static final int CPCL_STATE_PAPER_ERR = 0x01;/*** CPCL指令查詢打印機實時狀態(tài) 打印機開蓋狀態(tài)*/private static final int CPCL_STATE_COVER_OPEN = 0x02;private byte[] sendCommand;/*** 判斷打印機所使用指令是否是ESC指令*/private PrinterCommand currentPrinterCommand;public static final byte FLAG = 0x10;private static final int READ_DATA = 10000;private static final String READ_DATA_CNT = "read_data_cnt";private static final String READ_BUFFER_ARRAY = "read_buffer_array";public static final String ACTION_CONN_STATE = "action_connect_state";public static final String ACTION_QUERY_PRINTER_STATE = "action_query_printer_state";public static final String STATE = "state";public static final String DEVICE_ID = "id";public static final int CONN_STATE_DISCONNECT = 0x90;public static final int CONN_STATE_CONNECTING = CONN_STATE_DISCONNECT << 1;public static final int CONN_STATE_FAILED = CONN_STATE_DISCONNECT << 2;public static final int CONN_STATE_CONNECTED = CONN_STATE_DISCONNECT << 3;public PrinterReader reader;private String status="打印機連接正常";public enum CONN_METHOD {//藍牙連接BLUETOOTH("BLUETOOTH"),//USB連接USB("USB"),//wifi連接WIFI("WIFI"),//串口連接SERIAL_PORT("SERIAL_PORT");private String name;private CONN_METHOD(String name) {this.name = name;}@Overridepublic String toString() {return this.name;}}public static DeviceConnFactoryManager[] getDeviceConnFactoryManagers() {return deviceConnFactoryManagers;}/*** 打開端口** @return*/public void openPort() {deviceConnFactoryManagers[id].isOpenPort = false;sendStateBroadcast(CONN_STATE_CONNECTING);switch (deviceConnFactoryManagers[id].connMethod) {case BLUETOOTH:System.out.println("id -> " + id);mPort = new BluetoothPort(macAddress);isOpenPort = deviceConnFactoryManagers[id].mPort.openPort();break;case USB:mPort = new UsbPort(mContext, mUsbDevice);isOpenPort = mPort.openPort();if (isOpenPort) {IntentFilter filter = new IntentFilter(ACTION_USB_DEVICE_DETACHED);mContext.registerReceiver(usbStateReceiver, filter);}break;case WIFI:mPort = new EthernetPort(ip, port);isOpenPort = mPort.openPort();break;case SERIAL_PORT:mPort = new SerialPort(serialPortPath, baudrate, 0);isOpenPort = mPort.openPort();break;default:break;}//端口打開成功后,檢查連接打印機所使用的打印機指令ESC、TSCif (isOpenPort) {queryCommand();} else {if (this.mPort != null) {this.mPort=null;}sendStateBroadcast(CONN_STATE_FAILED);}}/*** 查詢當前連接打印機所使用打印機指令(ESC(EscCommand.java)、TSC(LabelCommand.java))*/private void queryCommand() {//開啟讀取打印機返回數(shù)據(jù)線程reader = new PrinterReader();reader.start(); //讀取數(shù)據(jù)線程//查詢打印機所使用指令queryPrinterCommand(); //}/*** 獲取端口連接方式** @return*/public CONN_METHOD getConnMethod() {return connMethod;}/*** 獲取端口打開狀態(tài)(true 打開,false 未打開)** @return*/public boolean getConnState() {return isOpenPort;}/*** 獲取連接藍牙的物理地址** @return*/public String getMacAddress() {return macAddress;}/*** 獲取連接網(wǎng)口端口號** @return*/public int getPort() {return port;}/*** 獲取連接網(wǎng)口的IP** @return*/public String getIp() {return ip;}/*** 獲取連接的USB設備信息** @return*/public UsbDevice usbDevice() {return mUsbDevice;}/*** 關閉端口*/public void closePort(int id) {if (this.mPort != null) {System.out.println("id -> " + id);reader.cancel();boolean b= this.mPort.closePort();if(b) {this.mPort=null;isOpenPort = false;currentPrinterCommand = null;}}sendStateBroadcast(CONN_STATE_DISCONNECT);}/*** 獲取串口號** @return*/public String getSerialPortPath() {return serialPortPath;}/*** 獲取波特率** @return*/public int getBaudrate() {return baudrate;}public static void closeAllPort() {for (DeviceConnFactoryManager deviceConnFactoryManager : deviceConnFactoryManagers) {if (deviceConnFactoryManager != null) {Log.e(TAG, "cloaseAllPort() id -> " + deviceConnFactoryManager.id);deviceConnFactoryManager.closePort(deviceConnFactoryManager.id);deviceConnFactoryManagers[deviceConnFactoryManager.id] = null;}}}private DeviceConnFactoryManager(Build build) {this.connMethod = build.connMethod;this.macAddress = build.macAddress;this.port = build.port;this.ip = build.ip;this.mUsbDevice = build.usbDevice;this.mContext = build.context;this.serialPortPath = build.serialPortPath;this.baudrate = build.baudrate;this.id = build.id;deviceConnFactoryManagers[id] = this;}/*** 獲取當前打印機指令** @return PrinterCommand*/public PrinterCommand getCurrentPrinterCommand() {return deviceConnFactoryManagers[id].currentPrinterCommand;}public static final class Build {private String ip;private String macAddress;private UsbDevice usbDevice;private int port;private CONN_METHOD connMethod;private Context context;private String serialPortPath;private int baudrate;private int id;public DeviceConnFactoryManager.Build setIp(String ip) {this.ip = ip;return this;}public DeviceConnFactoryManager.Build setMacAddress(String macAddress) {this.macAddress = macAddress;return this;}public DeviceConnFactoryManager.Build setUsbDevice(UsbDevice usbDevice) {this.usbDevice = usbDevice;return this;}public DeviceConnFactoryManager.Build setPort(int port) {this.port = port;return this;}public DeviceConnFactoryManager.Build setConnMethod(CONN_METHOD connMethod) {this.connMethod = connMethod;return this;}public DeviceConnFactoryManager.Build setContext(Context context) {this.context = context;return this;}public DeviceConnFactoryManager.Build setId(int id) {this.id = id;return this;}public DeviceConnFactoryManager.Build setSerialPort(String serialPortPath) {this.serialPortPath = serialPortPath;return this;}public DeviceConnFactoryManager.Build setBaudrate(int baudrate) {this.baudrate = baudrate;return this;}public DeviceConnFactoryManager build() {return new DeviceConnFactoryManager(this);}}public void sendDataImmediately(final Vector<Byte> data) {if (this.mPort == null) {return;}try {// Log.e(TAG, "data -> " + new String(com.gprinter.command.GpUtils.convertVectorByteTobytes(data), "gb2312"));this.mPort.writeDataImmediately(data, 0, data.size());} catch (Exception e) {e.printStackTrace();}}public int readDataImmediately(byte[] buffer) throws IOException {return this.mPort.readData(buffer);}/*** 查詢打印機當前使用的指令(TSC、ESC)*/private void queryPrinterCommand() {//線程池添加任務ThreadPool.getInstantiation().addTask(new Runnable() {@Overridepublic void run() {//發(fā)送ESC查詢打印機狀態(tài)指令sendCommand = esc;Vector<Byte> data = new Vector<>(esc.length);for (int i = 0; i < esc.length; i++) {data.add(esc[i]);}sendDataImmediately(data); //發(fā)送esc數(shù)據(jù)//開啟計時器,隔2000毫秒沒有沒返回值時發(fā)送TSC查詢打印機狀態(tài)指令final ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder("Timer");final ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, threadFactoryBuilder);scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {@Overridepublic void run() {if (currentPrinterCommand == null || currentPrinterCommand != PrinterCommand.ESC) {Log.e(TAG, Thread.currentThread().getName());//發(fā)送TSC查詢打印機狀態(tài)指令sendCommand = tsc;Vector<Byte> data = new Vector<>(tsc.length);for (int i = 0; i < tsc.length; i++) {data.add(tsc[i]);}sendDataImmediately(data);//開啟計時器,隔2000毫秒沒有沒返回值時發(fā)送CPCL查詢打印機狀態(tài)指令scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {@Overridepublic void run() {if (currentPrinterCommand == null||(currentPrinterCommand != PrinterCommand.ESC&¤tPrinterCommand != PrinterCommand.TSC)) {Log.e(TAG, Thread.currentThread().getName());//發(fā)送CPCL查詢打印機狀態(tài)指令sendCommand=cpcl;Vector<Byte> data =new Vector<Byte>(cpcl.length);for (int i=0;i<cpcl.length;i++){data.add(cpcl[i]);}sendDataImmediately(data);//開啟計時器,隔2000毫秒打印機沒有響應者停止讀取打印機數(shù)據(jù)線程并且關閉端口scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {@Overridepublic void run() {if(currentPrinterCommand==null){if (reader != null) {reader.cancel();mPort.closePort();isOpenPort = false;mPort=null;sendStateBroadcast(CONN_STATE_FAILED);}}}}),2000, TimeUnit.MILLISECONDS);}}}), 2000, TimeUnit.MILLISECONDS);}}}), 2000, TimeUnit.MILLISECONDS);}});}public class PrinterReader extends Thread {private boolean isRun = false;private byte[] buffer = new byte[100];public PrinterReader() {isRun = true;}@Overridepublic void run() {try {while (isRun) {//讀取打印機返回信息int len = readDataImmediately(buffer);if (len > 0) {Message message = Message.obtain();message.what = READ_DATA;Bundle bundle = new Bundle();bundle.putInt(READ_DATA_CNT, len); //數(shù)據(jù)長度bundle.putByteArray(READ_BUFFER_ARRAY, buffer); //數(shù)據(jù)message.setData(bundle);mHandler.sendMessage(message);}}} catch (Exception e) {if (deviceConnFactoryManagers[id] != null) {closePort(id);}}}public void cancel() {isRun = false;}}private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case READ_DATA:int cnt = msg.getData().getInt(READ_DATA_CNT); //數(shù)據(jù)長度 >0;byte[] buffer = msg.getData().getByteArray(READ_BUFFER_ARRAY); //數(shù)據(jù)//這里只對查詢狀態(tài)返回值做處理,其它返回值可參考編程手冊來解析if (buffer == null) {return;}int result = judgeResponseType(buffer[0]); //數(shù)據(jù)右移//String status = AppApplication.getInstance().getString(R.string.str_printer_conn_normal);if (sendCommand == esc) {//設置當前打印機模式為ESC模式if (currentPrinterCommand == null) {currentPrinterCommand = PrinterCommand.ESC;sendStateBroadcast(CONN_STATE_CONNECTED);} else {//查詢打印機狀態(tài)if (result == 0) {//打印機狀態(tài)查詢Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);} else if (result == 1) {//查詢打印機實時狀態(tài)if ((buffer[0] & ESC_STATE_PAPER_ERR) > 0) {//缺紙status =AppApplication.getInstance().getString(R.string.str_printer_out_of_paper);ToastUtil.showToastWithImg(status,R.drawable.ico_fail);}if ((buffer[0] & ESC_STATE_COVER_OPEN) > 0) {//開蓋status =AppApplication.getInstance().getString(R.string.str_printer_open_cover);ToastUtil.showToastWithImg(status,R.drawable.ico_fail);}if ((buffer[0] & ESC_STATE_ERR_OCCURS) > 0) {status =AppApplication.getInstance().getString(R.string.str_printer_error);ToastUtil.showToastWithImg(status,R.drawable.ico_fail);}System.out.println(AppApplication.getInstance().getString(R.string.str_state) + status);// String mode=AppApplication.getInstance().getString(R.string.str_printer_printmode_esc);//Utils.toast(AppApplication.getInstance(), mode+" "+status);}}} else if (sendCommand == tsc) {//設置當前打印機模式為TSC模式if (currentPrinterCommand == null) {currentPrinterCommand = PrinterCommand.TSC;sendStateBroadcast(CONN_STATE_CONNECTED);} else {if (cnt == 1) {//查詢打印機實時狀態(tài)if ((buffer[0] & TSC_STATE_PAPER_ERR) > 0) {//缺紙status =AppApplication.getInstance().getString(R.string.str_printer_out_of_paper);}if ((buffer[0] & TSC_STATE_COVER_OPEN) > 0) {//開蓋status =AppApplication.getInstance().getString(R.string.str_printer_open_cover);}if ((buffer[0] & TSC_STATE_ERR_OCCURS) > 0) {//打印機報錯status =AppApplication.getInstance().getString(R.string.str_printer_error);}System.out.println(AppApplication.getInstance().getString(R.string.str_state) + status);String mode=AppApplication.getInstance().getString(R.string.str_printer_printmode_tsc);Utils.toast(AppApplication.getInstance(), mode+" "+status);} else {//打印機狀態(tài)查詢Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);}}}else if(sendCommand==cpcl){if (currentPrinterCommand == null) {currentPrinterCommand = PrinterCommand.CPCL;sendStateBroadcast(CONN_STATE_CONNECTED);}else {if (cnt == 1) {System.out.println(AppApplication.getInstance().getString(R.string.str_state) + status);if ((buffer[0] ==CPCL_STATE_PAPER_ERR)) {//缺紙status =AppApplication.getInstance().getString(R.string.str_printer_out_of_paper);}if ((buffer[0] ==CPCL_STATE_COVER_OPEN)) {//開蓋status =AppApplication.getInstance().getString(R.string.str_printer_open_cover);}String mode=AppApplication.getInstance().getString(R.string.str_printer_printmode_cpcl);Utils.toast(AppApplication.getInstance(), mode+" "+status);} else {//打印機狀態(tài)查詢Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);}}}break;default:break;}}};public String getStatus(){return status;}private void sendStateBroadcast(int state) {Intent intent = new Intent(ACTION_CONN_STATE);intent.putExtra(STATE, state);intent.putExtra(DEVICE_ID, id);AppApplication.getInstance().sendBroadcast(intent);}/*** 判斷是實時狀態(tài)(10 04 02)還是查詢狀態(tài)(1D 72 01)*/private int judgeResponseType(byte r) {return (byte) ((r & FLAG) >> 4);}BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();switch (action) {case ACTION_USB_DEVICE_DETACHED:sendStateBroadcast(CONN_STATE_DISCONNECT);break;default:break;}}};}打印操作
//打印切刀命令 byte[] bytes={29,86,0}; //實時狀態(tài)查詢 byte[] bytes1={16,4,2}; private void sendReceiptWithResponse() {EscCommand esc = new EscCommand();esc.addInitializePrinter();esc.addPrintAndFeedLines((byte) 1);// 設置打印居中esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 設置為倍高倍寬esc.addText(""+AppApplication.getInstance().getDaoSession().getBusinessSettingDao().loadAll().get(0).getPRINTTITLE()+"\n");esc.addText("[商戶存根]\n");esc.addPrintAndLineFeed();// 設置打印左對齊esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);// 打印文字esc.addText("----------------------------\n");// 打印文字esc.addText("商戶號: "+AppApplication.getInstance().getDaoSession().getDeviceInfoDao().loadAll().get(0).getStoreNum()+"\n");esc.addText("商戶名稱: "+AppApplication.getInstance().getDaoSession().getDeviceInfoDao().loadAll().get(0).getStoreName()+"\n");esc.addText("員工卡號: "+businessDetail.getWiegand_id()+"\n");esc.addText("交易賬號: "+businessDetail.getCARDNUM()+"\n");esc.addText("交易類型: "+businessDetail.getTYPE()+"\n");esc.addText("訂單號: "+businessDetail.getORDERNUM()+"\n");esc.addText("日期時間: "+businessDetail.getDATE()+"\n");if (businessDetail.getTYPE().equals("消費")){esc.addText("交易金額: RMB "+businessDetail.getMONEY()+"\n");}else {esc.addText("交易金額: RMB -"+businessDetail.getMONEY()+"\n");}esc.addText("----------------------------\n");esc.addText("備注\n");esc.addPrintAndLineFeed();esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 開錢箱esc.addGeneratePlus(LabelCommand.FOOT.F5, (byte) 255, (byte) 255);esc.addPrintAndFeedLines((byte) 8);// 加入查詢打印機狀態(tài),用于連續(xù)打印esc.addUserCommand(bytes);Vector<Byte> datas = esc.getCommand();// 發(fā)送數(shù)據(jù)DeviceConnFactoryManager.getDeviceConnFactoryManagers()[0].sendDataImmediately(datas);if(Integer.valueOf(AppApplication.getInstance().getDaoSession().getBusinessSettingDao().loadAll().get(0).getPRINTPAGE())>1){sendReceiptWithResponse1();}}總結
以上是生活随笔為你收集整理的android 佳博蓝牙打印机功能开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库应用——Redis详解
- 下一篇: 高权重链接与一般性权重链接