В одном приложении для Android я встроил функцию печати чеков прямо из приложения с использованием термопринтера. Я использую класс «UsbDeviceConnection» для печати квитанции.
Это не всегда работает должным образом. Например, если я распечатываю квитанцию, она печатается один раз, затем, если я отправляю печать снова, она записывает все байты в соединение с принтером, но на самом деле не печатает квитанцию.
Чтобы снова распечатать квитанцию, мне нужноперезагрузить принтер один раз. Поэтому, если я перезагружу свой термопринтер, я могу снова распечатать квитанцию.
Я использую нижеуказанный класс для печати квитанции.
public class UsbCommunicator {
private UsbManager mUsbManager;
private PendingIntent mPermissionIntent;
private UsbDevice selectedUsbDevice;
private UsbInterface selectedUsbInterface;
private int endpointOutId;
private int endpointInId;
private final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
public UsbCommunicator2(Context context) {
// Create USB manager
mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// Set USB permissions broadcaster
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
context.registerReceiver(mUsbReceiver, new IntentFilter(ACTION_USB_PERMISSION));
}
public ArrayList<UsbDevice> getConnectedDevices() {
ArrayList<UsbDevice> usbDevices = new ArrayList<>();
// Get every connected USB device and store in HashMap
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
// Loop through every connected USB device
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
usbDevices.add(device);
}
return usbDevices;
}
public void setDevice(UsbDevice device) {
if (!mUsbManager.hasPermission(device))
mUsbManager.requestPermission(device, mPermissionIntent);
else {
selectedUsbDevice = device;
setDeviceInterface(device);
setDeviceEndpoints(device);
}
}
public void sendData(byte[] bytes, CommunicationListener commListener) {
if (!deviceSelected() || !hasPermission()) return;
UsbEndpoint outputEndpoint = selectedUsbInterface.getEndpoint(endpointOutId);
new CommunicatorTask(commListener, outputEndpoint, bytes).execute();
}
public boolean deviceSelected() {
return selectedUsbDevice != null ? true : false;
}
public boolean hasPermission() {
return deviceSelected() && mUsbManager.hasPermission(selectedUsbDevice);
}
private void setDeviceInterface(UsbDevice device) {
// Get the device interface, this is known to be 0 for the targetted Star and Sanei devices, but can vary for other devices
selectedUsbInterface = device.getInterface(0);
}
private void setDeviceEndpoints(UsbDevice device) {
if (selectedUsbInterface == null) return;
// Loop through every end point on the interface to find the right end points
for (int i = 0; i < selectedUsbInterface.getEndpointCount(); i++) {
UsbEndpoint endpoint = selectedUsbInterface.getEndpoint(i);
if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT)
endpointOutId = i;
else if (endpoint.getDirection() == UsbConstants.USB_DIR_IN)
endpointInId = i;
}
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
// Device permission was granted
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
selectedUsbDevice = device;
setDeviceInterface(device);
setDeviceEndpoints(device);
}
}
}
}
}
};
private class CommunicatorTask extends AsyncTask<Void, Void, Integer> {
private CommunicationListener commListener;
private UsbEndpoint outputEndpoint;
private byte[] bytes;
private UsbDeviceConnection connection;
public CommunicatorTask(CommunicationListener commListener, UsbEndpoint outputEndpoint, byte[] bytes) {
this.commListener = commListener;
this.outputEndpoint = outputEndpoint;
this.bytes = bytes;
connection = mUsbManager.openDevice(selectedUsbDevice);
connection.claimInterface(selectedUsbInterface, true);
}
protected Integer doInBackground(Void... unused) {
int bytesWritten = 0;
while (bytesWritten < bytes.length) {
bytesWritten += connection.bulkTransfer(outputEndpoint, bytes, bytesWritten, bytes.length - bytesWritten, 0);
}
return bytesWritten;
}
protected void onPostExecute(Integer bytesTransferred) {
connection.close();
commListener.onComplete(bytesTransferred);
}
}
}
Ниже приведен код в моем файле активности.
UsbCommunicator usbComm = new UsbCommunicator(context);
ArrayList<UsbDevice> connectedDevices = usbComm.getConnectedDevices();
if(connectedDevices.size() == 0) {
Toast.makeText(context, "No USB Printer Detected", Toast.LENGTH_SHORT).show();
return;
}
UsbDevice device = connectedDevices.get(0);
usbComm.setDevice(device);
Bytes[] bytes = createSampleReceipt(imgPath); << This method will convert Image to Bytes array
usbComm.sendData(bytes, new CommunicationListener(){
@Override
public void onComplete(int bytesTransferred) {
Toast.makeText(context, "Printer Success", Toast.LENGTH_SHORT).show();
}
});
В этом случае печать работает только один раз, а затем для печати другой квитанции, мне нужно перезапустить термопринтер. В реальном сценарии он должен отправлять все распечатки согласно запросу и не требует перезагрузки принтера.