#java #android
#java #Android
Вопрос:
Я использую следующий код для печати файла через USB OTG на принтере Epson l380. У меня нет проблем с подключением, даже в коде я передаю файл pdf в байты, а затем создаю его снова, чтобы проверить правильность байтов. Проблема в том, что когда данные передаются на «массовую передачу», принтер печатает неправильные символы в документе pdf. Я прилагаю код и фотографию редких символов, которые он печатает.
package com.example.test_usb;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
public class MainActivity extends AppCompatActivity {
private UsbManager mUsbManager;
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private UsbInterface mInterface;
private UsbEndpoint mEndPoint;
private PendingIntent mPermissionIntent;
EditText TxtEntrada;
Button BtnImprimir;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private static Boolean forceCLaim = true;
private byte [] ByteArray;
HashMap<String, UsbDevice> mDeviceList;
Iterator<UsbDevice> mDeviceIterator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TxtEntrada = (EditText) findViewById(R.id.TxtEntrada);
BtnImprimir = (Button) findViewById(R.id.BtnImprimir);
try{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mDeviceList = mUsbManager.getDeviceList();
}
}catch (Exception e){
Log.d("ERROR :",e.toString());
}
if (mDeviceList.size() > 0) {
mDeviceIterator = mDeviceList.values().iterator();
Toast.makeText(this, "Device List Size: " String.valueOf(mDeviceList.size()), Toast.LENGTH_SHORT).show();
TextView textView = (TextView) findViewById(R.id.BoxViewUSB);
String usbDevice = "";
while (mDeviceIterator.hasNext()) {
UsbDevice usbDevice1 = mDeviceIterator.next();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
usbDevice = "n"
"DeviceID: " usbDevice1.getDeviceId() "n"
"DeviceName: " usbDevice1.getDeviceName() "n"
"Protocol: " usbDevice1.getDeviceProtocol() "n"
"Product Name: " usbDevice1.getProductName() "n"
"Manufacturer Name: " usbDevice1.getManufacturerName() "n"
"DeviceClass: " usbDevice1.getDeviceClass() " - " translateDeviceClass(usbDevice1.getDeviceClass()) "n"
"DeviceSubClass: " usbDevice1.getDeviceSubclass() "n"
"VendorID: " usbDevice1.getVendorId() "n"
"ProductID: " usbDevice1.getProductId() "n";
}
int interfaceCount = usbDevice1.getInterfaceCount();
Toast.makeText(this, "INTERFACE COUNT: " String.valueOf(interfaceCount), Toast.LENGTH_SHORT).show();
mDevice = usbDevice1;
Toast.makeText(this, "Device is attached", Toast.LENGTH_SHORT).show();
textView.setText(usbDevice);
}
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
mUsbManager.requestPermission(mDevice, mPermissionIntent);
} else {
Toast.makeText(this, "Please attach printer via USB", Toast.LENGTH_SHORT).show();
}
BtnImprimir.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
print(mConnection, mInterface);
}
});
}
private void print(final UsbDeviceConnection connection, final UsbInterface usbInterface) {
if (usbInterface == null) {
Toast.makeText(this, "INTERFACE IS NULL", Toast.LENGTH_SHORT).show();
} else if (connection == null) {
Toast.makeText(this, "CONNECTION IS NULL", Toast.LENGTH_SHORT).show();
} else if (forceCLaim == null) {
Toast.makeText(this, "FORCE CLAIM IS NULL", Toast.LENGTH_SHORT).show();
} else {
connection.claimInterface(usbInterface, forceCLaim);
try {
//Pdf To byte
ByteArray= loadFile("/storage/emulated/0/Download/Prueba.pdf");
//byte to create Pdf
OutputStream out = new FileOutputStream("/storage/emulated/0/Download/leer.pdf");
out.write(ByteArray);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
byte[] cut_paper = {0x1D, 0x56, 0x41, 0x10};
connection.bulkTransfer(mEndPoint, ByteArray, ByteArray.length, 0);
connection.bulkTransfer(mEndPoint, cut_paper, cut_paper.length, 0);
Toast.makeText(MainActivity.this, "RUN PROCESS !" , Toast.LENGTH_SHORT).show();
}
});
thread.run();
}
}
public static byte[] loadFile(String sourcePath) throws IOException
{
InputStream inputStream = null;
try
{
inputStream = new FileInputStream(sourcePath);
return readFully(inputStream);
}
finally
{
if (inputStream != null)
{
inputStream.close();
}
}
}
public static byte[] readFully(InputStream stream) throws IOException
{
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = stream.read(buffer)) != -1)
{
baos.write(buffer, 0, bytesRead);
}
return baos.toByteArray();
}
final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
//call method to set up device communication
mInterface = device.getInterface(1);
mEndPoint = mInterface.getEndpoint(1);// 0 IN and 1 OUT to printer.
mConnection = mUsbManager.openDevice(device);
}
} else {
Toast.makeText(context, "PERMISSION DENIED FOR THIS DEVICE", Toast.LENGTH_SHORT).show();
}
}
}
}
};
private String translateDeviceClass(int deviceClass) {
switch (deviceClass) {
case UsbConstants.USB_CLASS_APP_SPEC:
return "Application specific USB class";
case UsbConstants.USB_CLASS_AUDIO:
return "USB class for audio devices";
case UsbConstants.USB_CLASS_CDC_DATA:
return "USB class for CDC devices (communications device class)";
case UsbConstants.USB_CLASS_COMM:
return "USB class for communication devices";
case UsbConstants.USB_CLASS_CONTENT_SEC:
return "USB class for content security devices";
case UsbConstants.USB_CLASS_CSCID:
return "USB class for content smart card devices";
case UsbConstants.USB_CLASS_HID:
return "USB class for human interface devices (for example, mice and keyboards)";
case UsbConstants.USB_CLASS_HUB:
return "USB class for USB hubs";
case UsbConstants.USB_CLASS_MASS_STORAGE:
return "USB class for mass storage devices";
case UsbConstants.USB_CLASS_MISC:
return "USB class for wireless miscellaneous devices";
case UsbConstants.USB_CLASS_PER_INTERFACE:
return "USB class indicating that the class is determined on a per-interface basis";
case UsbConstants.USB_CLASS_PHYSICA:
return "USB class for physical devices";
case UsbConstants.USB_CLASS_PRINTER:
return "USB class for printers";
case UsbConstants.USB_CLASS_STILL_IMAGE:
return "USB class for still image devices (digital cameras)";
case UsbConstants.USB_CLASS_VENDOR_SPEC:
return "Vendor specific USB class";
case UsbConstants.USB_CLASS_VIDEO:
return "USB class for video devices";
case UsbConstants.USB_CLASS_WIRELESS_CONTROLLER:
return "USB class for wireless controller devices";
default:
return "Unknown USB class!";
}
}
}
Фотография неправильных символов, которые вы печатаете, выглядит следующим образом.
Редкие символы файла PDF
Мне нужна помощь, чтобы этого не произошло, пожалуйста!
Комментарии:
1.
Toast.makeText(MainActivity.this, "RUN PROCESS !" ,....
Вы не можете отобразить всплывающее окно в run() потока. Невозможный код.2. ах да, извините, у меня было это раньше для тестирования с другим циклом потока, но, пожалуйста, проигнорируйте этот тост
Ответ №1:
Принтеры не знают, что такое «PDF».
Вы не можете просто взять PDF-файл, сбросить его через USB и ожидать, что он будет напечатан.
В вашем случае принтер был достаточно любезен, чтобы интерпретировать данные как поток ASCII, поэтому он печатал части метаданных PDF на английском языке, а остальные символы соответствовали любым полученным значениям байтов.
Если вы хотите написать приложение для Android, которое может печатать напрямую через USB-соединение, вам придется выполнить 2 огромные задачи:
- Повторно внедрите драйвер принтера на Java (специфичный для вашего принтера).
- Реализуйте функциональность рендеринга PDF, которая будет «понимать» PDF-документ и отображать его на принтере с помощью соответствующих команд (для настройки шрифтов, размеров, позиций и рисования графики, когда это необходимо).
Это далеко за пределами SO, но в Интернете есть много ресурсов и программ с открытым исходным кодом, так что удачи!
Комментарии:
1. Большое спасибо! Я много думал об этом, так как я новичок в Java, и я думал, что отправка данных решит эту проблему