How to print an image with bulktransfer() in Android

April 18, 2022, at 10:10 PM

I'm new to Android. i need to print an image via USB. I came across bulktransfer() by looking at the android development documentation. Following the example, I succeeded in printing text to a usb printer.However, if the data of a file such as an image (.jpg, .png, .pdf...) is saved in a bytearray and printed, the format of the file is printed as text. Also, when data is printed as text, the layout is output abnormally. Attach an image.

As in the attached image, the layout is abnormal, and the next data goes to the next page and is printed on a new sheet of paper. I've done a search, but the example is just text printing.

If you know a simple example or method to print an image through a USB printer on Android, please tell me how. thank you.

Source Code

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
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.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.StandardCharsets;
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 ed_txt;
    private static final String ACTION_USB_PERMISSION = "";
    private static Boolean forceCLaim = true;
    HashMap<String, UsbDevice> mDeviceList;
    Iterator<UsbDevice> mDeviceIterator;
    byte[] testBytes;

    protected void onCreate(Bundle savedInstanceState) {

        ed_txt = (EditText) findViewById(;
        Button print = (Button) findViewById(;
        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        mDeviceList = mUsbManager.getDeviceList();
        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(;
            String usbDevice = "";
            while (mDeviceIterator.hasNext()) {
                UsbDevice usbDevice1 =;
                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();
            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, "USB를 연결해주세요.", Toast.LENGTH_SHORT).show();
        print.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                try {
                    print(mConnection, mInterface);
                } catch (IOException e) {
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if(height > reqHeight || width > reqWidth){
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth){
                inSampleSize *= 2;
        return inSampleSize;
    public static Bitmap decodeSampleBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight){
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    public byte[] bitmapToByteArray(Bitmap bitmap){
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        return byteArray;

    private void print(final UsbDeviceConnection connection, final UsbInterface usbInterface) throws IOException {
        final String test = ed_txt.getText().toString();
        testBytes = test.getBytes(StandardCharsets.UTF_8);
        Bitmap bit = decodeSampleBitmapFromResource(getResources(),, 100, 300);
        testBytes = bitmapToByteArray(bit);

        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);
            connection.bulkTransfer(mEndPoint, testBytes, testBytes.length, 0);

    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 = (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(0);
                            mEndPoint = mInterface.getEndpoint(0);// 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";
                return "Unknown USB class!";
Rent Charter Buses Company
How can I create a wrapper for the RecyclerView Adapter that will accept any Adapter that implements RecyclerView.Adapter&lt;RecyclerView.ViewHolder&gt;

How can I create a wrapper for the RecyclerView Adapter that will accept any Adapter that implements RecyclerView.Adapter<RecyclerView.ViewHolder>

I know the title is a bit weird, sorryThis is a weird one that I'm not even sure I can explain it correctly, here is my attempt:

Why in the fragment inside the bottomNavigation, the request is not sent to the server from the second time onwards

Why in the fragment inside the bottomNavigation, the request is not sent to the server from the second time onwards

I have a bottom navigation and when switch between its items In two cases, two different things happen : First : When the program is first run -> Everything works finethat's mean: enter image description here

user = discord.utils.get(client.users, name=&quot;name&quot;, discriminator=&quot;0000&quot;) comes back with none

user = discord.utils.get(client.users, name="name", discriminator="0000") comes back with none

So i want to be able to mention a user when I input there name and discriminator but I cant get it to work as it keeps return none

What is the logic behind this fstring in python?

What is the logic behind this fstring in python?

From this question: Converting an integer to signed 2's complement binary string