蓝牙自动连接已配对设备
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("暂无配对设备");
}
}
根据蓝牙地址,初始化线程池去做连接操作
private void connect(String address){
deviceConnFactoryManager=new DeviceConnFactoryManager.Build()
.setId(0)
.setConnMethod(DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH)
.setMacAddress(address)
.build();
ThreadPool.getInstantiation().addTask(new Runnable() {
@Override
public 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;
private byte[] esc = {0x10, 0x04, 0x02};
private static final int ESC_STATE_PAPER_ERR = 0x20;
private static final int ESC_STATE_COVER_OPEN = 0x04;
private static final int ESC_STATE_ERR_OCCURS = 0x40;
private byte[] tsc = {0x1b, '!', '?'};
private static final int TSC_STATE_PAPER_ERR = 0x04;
private static final int TSC_STATE_COVER_OPEN = 0x01;
private static final int TSC_STATE_ERR_OCCURS = 0x80;
private byte[] cpcl={0x1b,0x68};
private static final int CPCL_STATE_PAPER_ERR = 0x01;
private static final int CPCL_STATE_COVER_OPEN = 0x02;
private byte[] sendCommand;
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"),
WIFI("WIFI"),
SERIAL_PORT("SERIAL_PORT");
private String name;
private CONN_METHOD(String name) {
this.name = name;
}
@Override
public String toString() {
return this.name;
}
}
public static DeviceConnFactoryManager[] getDeviceConnFactoryManagers() {
return deviceConnFactoryManagers;
}
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;
}
if (isOpenPort) {
queryCommand();
} else {
if (this.mPort != null) {
this.mPort=null;
}
sendStateBroadcast(CONN_STATE_FAILED);
}
}
private void queryCommand() {
reader = new PrinterReader();
reader.start();
queryPrinterCommand();
}
public CONN_METHOD getConnMethod() {
return connMethod;
}
public boolean getConnState() {
return isOpenPort;
}
public String getMacAddress() {
return macAddress;
}
public int getPort() {
return port;
}
public String getIp() {
return ip;
}
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);
}
public String getSerialPortPath() {
return serialPortPath;
}
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;
}
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 {
this.mPort.writeDataImmediately(data, 0, data.size());
} catch (Exception e) {
e.printStackTrace();
}
}
public int readDataImmediately(byte[] buffer) throws IOException {
return this.mPort.readData(buffer);
}
private void queryPrinterCommand() {
ThreadPool.getInstantiation().addTask(new Runnable() {
@Override
public void run() {
sendCommand = esc;
Vector<Byte> data = new Vector<>(esc.length);
for (int i = 0; i < esc.length; i++) {
data.add(esc[i]);
}
sendDataImmediately(data);
final ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder("Timer");
final ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, threadFactoryBuilder);
scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {
@Override
public void run() {
if (currentPrinterCommand == null || currentPrinterCommand != PrinterCommand.ESC) {
Log.e(TAG, Thread.currentThread().getName());
sendCommand = tsc;
Vector<Byte> data = new Vector<>(tsc.length);
for (int i = 0; i < tsc.length; i++) {
data.add(tsc[i]);
}
sendDataImmediately(data);
scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {
@Override
public void run() {
if (currentPrinterCommand == null||(currentPrinterCommand != PrinterCommand.ESC&¤tPrinterCommand != PrinterCommand.TSC)) {
Log.e(TAG, Thread.currentThread().getName());
sendCommand=cpcl;
Vector<Byte> data =new Vector<Byte>(cpcl.length);
for (int i=0;i<cpcl.length;i++){
data.add(cpcl[i]);
}
sendDataImmediately(data);
scheduledExecutorService.schedule(threadFactoryBuilder.newThread(new Runnable() {
@Override
public 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;
}
@Override
public 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);
bundle.putByteArray(READ_BUFFER_ARRAY, buffer);
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() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case READ_DATA:
int cnt = msg.getData().getInt(READ_DATA_CNT);
byte[] buffer = msg.getData().getByteArray(READ_BUFFER_ARRAY);
if (buffer == null) {
return;
}
int result = judgeResponseType(buffer[0]);
if (sendCommand == esc) {
if (currentPrinterCommand == null) {
currentPrinterCommand = PrinterCommand.ESC;
sendStateBroadcast(CONN_STATE_CONNECTED);
} else {
if (result == 0) {
Intent intent = new Intent(ACTION_QUERY_PRINTER_STATE);
intent.putExtra(DEVICE_ID, id);
AppApplication.getInstance().sendBroadcast(intent);
} else if (result == 1) {
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);
}
}
} else if (sendCommand == tsc) {
if (currentPrinterCommand == null) {
currentPrinterCommand = PrinterCommand.TSC;
sendStateBroadcast(CONN_STATE_CONNECTED);
} else {
if (cnt == 1) {
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 {
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 {
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);
}
private int judgeResponseType(byte r) {
return (byte) ((r & FLAG) >> 4);
}
BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {
@Override
public 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};
//实时状态查询
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);
esc.addUserCommand(bytes);
Vector<Byte> datas = esc.getCommand();
DeviceConnFactoryManager.getDeviceConnFactoryManagers()[0].sendDataImmediately(datas);
if(Integer.valueOf(AppApplication.getInstance().getDaoSession().getBusinessSettingDao().loadAll().get(0).getPRINTPAGE())>1){
sendReceiptWithResponse1();
}
}