принтер печатает редкие символы на Java с помощью массовой передачи

#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 огромные задачи:

  1. Повторно внедрите драйвер принтера на Java (специфичный для вашего принтера).
  2. Реализуйте функциональность рендеринга PDF, которая будет «понимать» PDF-документ и отображать его на принтере с помощью соответствующих команд (для настройки шрифтов, размеров, позиций и рисования графики, когда это необходимо).

Это далеко за пределами SO, но в Интернете есть много ресурсов и программ с открытым исходным кодом, так что удачи!

Комментарии:

1. Большое спасибо! Я много думал об этом, так как я новичок в Java, и я думал, что отправка данных решит эту проблему