资讯详情

Android之USB打印

文章目录

  • 前言
  • 一、效果图
  • 二、使用步骤
    • 1.UsbPrinter类
    • 2.ESCUtil类
    • 3.BytesUtil工具类
    • 4.Activity使用


前言

最近公司需要连接芯烨云的串口打印机,因为云打印有很多缺点,大家都知道,上菜要花什么钱!


一、效果图

常规出牌,先来效果图,不然你不感兴趣往下看! 在这里插入图片描述

二、使用步骤

1.UsbPrinter类

有注释就不用多说了!

package com.example.cashiersystem.utils;  import android.annotation.SuppressLint; import android.annotation.TargetApi; 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.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/** * 作者:CaoLiulang * ❤ * Date:2022/5/30 * ❤ * 模块:USB打印类 */
public class UsbPrinter{ 
        

    private static final String TAG = "UsbPrinter";
    public static final String ACTION_USB_PERMISSION = "com.usb.printer.USB_PERMISSION";
    @SuppressLint("StaticFieldLeak")
    private static UsbPrinter mInstance;
    private Context mContext;
    private PendingIntent mPermissionIntent;
    private UsbManager mUsbManager;
    private UsbDeviceConnection mUsbDeviceConnection;
    private UsbEndpoint ep, printerEp;
    private UsbInterface usbInterface;
    private static final int TIME_OUT = 100000;

    private UsbPrinter() { 
        
    }

    public static UsbPrinter getInstance() { 
        
        if (mInstance == null) { 
        
            synchronized (UsbPrinter.class) { 
        
                if (mInstance == null) { 
        
                    mInstance = new UsbPrinter();
                }
            }
        }
        return mInstance;
    }

    /** * 初始化打印机,需要与destroy对应 * * @param context 上下文 */
    public void initPrinter(Context context) { 
        
        init(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void init(Context context) { 
        
        mContext = context;
        mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
        // 注册广播监听usb设备
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        mContext.registerReceiver(mUsbDeviceReceiver, filter);
        // 列出所有的USB设备,并且都请求获取USB权限
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        for (UsbDevice device : deviceList.values()) { 
        
            // 得到此设备的一个接口
            usbInterface = device.getInterface(0);
            // 获取接口的类别 7代表连接的是打印机
            if (usbInterface.getInterfaceClass() == 7) { 
        
                // 1137 85 1027
                // 26728 1280 1045+2
                if (!mUsbManager.hasPermission(device)) { 
        
                    mUsbManager.requestPermission(device, mPermissionIntent);
                } else { 
        
                    connectUsbPrinter(device);
                }
            }
        }

    }

    private final BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() { 
        

        @Override
        public void onReceive(Context context, Intent intent) { 
        
            String action = intent.getAction();
            UsbDevice mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (ACTION_USB_PERMISSION.equals(action)) { 
        
                synchronized (this) { 
        
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false) && mUsbDevice != null) { 
        
                        connectUsbPrinter(mUsbDevice);
                    } else { 
        
                        ToastUtils.ToastCllShow( "USB设备请求被拒绝");
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { 
        
                if (mUsbDevice != null) { 
        
                    ToastUtils.ToastCllShow( "有设备拔出");
                }
            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) { 
        
                ToastUtils.ToastCllShow( "有设备插入");
                if (mUsbDevice != null) { 
        
                    if (!mUsbManager.hasPermission(mUsbDevice)) { 
        
                        mUsbManager.requestPermission(mUsbDevice, mPermissionIntent);
                    }
                }
            }
        }
    };

    /** * 关闭usb的端口及取消注册的广播监听 */
    public void close() { 
        
        if (mUsbDeviceConnection != null) { 
        
            mUsbDeviceConnection.close();
            mUsbDeviceConnection = null;
        }
        mContext.unregisterReceiver(mUsbDeviceReceiver);
        mContext = null;
        mUsbManager = null;
    }

    /** * 连接打印机设备 * * @param mUsbDevice 识别到的打印机设备 */
    private void connectUsbPrinter(UsbDevice mUsbDevice) { 
        
        if (mUsbDevice != null) { 
        
            for (int i = 0; i < usbInterface.getEndpointCount(); i++) { 
        
                // 获取指定的index 获得此接口的一个节点 返回一个UsbEndpoint
                ep = usbInterface.getEndpoint(i);
                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { 
        
                    if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { 
        
                        int pid = mUsbDevice.getProductId();
                        int vid = mUsbDevice.getVendorId();
                        mUsbDeviceConnection = mUsbManager.openDevice(mUsbDevice);
                        printerEp = ep;
                        if (mUsbDeviceConnection != null) { 
        
                            ToastUtils.ToastCllShow( "设备已连接");
                            // 在使用UsbInterface进行数据的写入写出之前,要申明对其的专有访问权限,防止通信混乱
                            mUsbDeviceConnection.claimInterface(usbInterface, true);
                        }
                    }
                }
            }
        } else { 
        
            ToastUtils.ToastCllShow( "未发现可用的打印机");
        }
    }

    /** * 安卓9.0之前 * 只要你传送的数据不大于16384 bytes,传送不会出问题,一旦数据大于16384 bytes,也可以传送, * 只是大于16384后面的数据就会丢失,获取到的数据永远都是前面的16384 bytes, * 所以,android USB Host 模式与HID使用bulkTransfer(endpoint,buffer,length,timeout)通讯时 * buffer的长度不能超过16384。 * <p> * controlTransfer( int requestType, int request , int value , int index , byte[] buffer , int length , int timeout) * 该方法通过0节点向此设备传输数据,传输的方向取决于请求的类别,如果requestType 为 USB_DIR_OUT 则为写数据 , USB _DIR_IN ,则为读数据 */
    private void write(byte[] bytes) { 
        
        if (mUsbDeviceConnection != null) { 
        
            // 通过给定的endpoint 来进行大量的数据传输,传输的方向取决于该节点的方向,
            // buffer是要发送或接收的字节数组,length是该字节数组的长度,失败则返回负数
            // 下行端点,字节数组消息,消息长度,响应时间
            int len = mUsbDeviceConnection.bulkTransfer(printerEp, bytes, bytes.length, TIME_OUT);
        } else { 
        
            if (Looper.myLooper()==null) { 
        
                Looper.prepare();
            }
            handler.sendEmptyMessage(0);
            Looper.loop();
        }
    }

    @SuppressLint("HandlerLeak")
    private final Handler handler = new Handler(Looper.getMainLooper()) { 
        
        @Override
        public void handleMessage(Message msg) { 
        
            super.handleMessage(msg);
            ToastUtils.ToastCllShow( "未发现可用的打印机");
        }
    };

    /** * 初始化 */
    public void init() { 
        
        write(ESCUtil.initPrinter());
    }

    /** * 打印文字 * * @param msg 打印的内容 */
    public void printText(String msg) { 
        
        byte[] bytes = new byte[0];
        try { 
        
            bytes = msg.getBytes("gbk");
        } catch (UnsupportedEncodingException e) { 
        
            e.printStackTrace();
        }
        write(bytes);
    }

    /** * 换行打印文字 * * @param msg 打印的内容 */
    public void printTextNewLine(String msg) { 
        
        byte[] bytes = new byte[0];
        try { 
        
            bytes = msg.getBytes("gbk");
        } catch (UnsupportedEncodingException e) { 
        
            e.printStackTrace();
        }
        write(new String("\n").getBytes());
        write(bytes);
    }

    /** * 换行 */
    public void printLine() { 
        
// write(new byte[]{10});
        write(new String("\n").getBytes());
    }

    /** * 打印空行 * * @param size 几行 */
    public void printLine(int size) { 
        
        for (int i = 0; i < size; i++) { 
        
            printText("\n");
        }
    }

    /** * 设置字体大小 * * @param size 0:正常大小 1:两倍高 2:两倍宽 3:两倍大小 4:三倍高 5:三倍宽 6:三倍大 7:四倍高 8:四倍宽 9:四倍大小 10:五倍高 11:五倍宽 12:五倍大小 */
    public void setTextSize(int size) { 
        
        write(ESCUtil.setTextSize(size));
    }

    /** * 字体加粗 * * @param isBold true/false */
    public void bold(boolean isBold) { 
        
        if (isBold) { 
        
            write(ESCUtil.boldOn());
        } else { 
        
            write(ESCUtil.boldOff());
        }
    }

    /** * 打印一维条形码 * * @param data 条码 */
    public void printBarCode(String data) { 
        
// write(ESCUtil.getPrintBarCode(data, 5, 90, 5, 2));
        write(ESCUtil.getPrintBarCode(data, 5, 90, 4, 2));
    }

    /** * 打印二维码 * * @param data 打印的内容 */
    public void printQrCode(String data) { 
        
        write(ESCUtil.getPrintQrCode(data, 250));
    }

    /** * 设置对齐方式 * * @param position 0居左 1居中 2居右 */
    public void setAlign(int position) { 
        
        byte[] bytes = null;
        switch (position) { 
        
            case 0:
                bytes = ESCUtil.alignLeft();
// bytes = new byte[]{ 0x1b, 0x61, 0x30 };
// bytes = new byte[]{27, 97, (byte) 0};
                break;
            case 1:
                bytes = ESCUtil.alignCenter();
// bytes = new byte[]{ 0x1b, 0x61, 0x31 };
// bytes = new byte[]{27, 97, (byte) 1};
                break;
            case 2:
                bytes = ESCUtil.alignRight();
// bytes = new byte[]{ 0x1b, 0x61, 0x32 };
// bytes = new byte[]{27, 97, (byte) 2};
                break;
            default:
                break;
        }
        write(bytes);
    }

    /** * 获取字符串的宽度 * * @param str 取字符 * @return 宽度 */
    public int getStringWidth(String str) { 
        
        int width = 0;
        for (char c : str.toCharArray()) { 
        
            width += isChinese(c) ? 2 : 1;
        }
        return width;
    }

    /** * 判断是否中文 * GENERAL_PUNCTUATION 判断中文的“号 * CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号 * HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的,号 * * @param c 字符 * @return 是否中文 */
    public static boolean isChinese(char c) { 
        
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION;
    }

    /** * 切纸 */
    public void cutPager() { 
        
        write(ESCUtil.cutter());
    }

}

2.ESCUtil类

代码如下(示例):

package com.example.cashiersystem.utils;

import android.graphics.Bitmap;

import java.io.ByteArrayOutputStream;

/** * 作者:CaoLiulang * ❤ * Date:2022/5/30 * ❤ * 模块:常用指令封装ESCUtil工具类 */
public class ESCUtil { 
        

    /** * Escape */
    public static final byte ESC = 0x1B;

    /** * Text delimiter 文本分隔符 */
    public static final byte FS = 0x1C;

    /** * Group separator 组分离器 */
    public static final byte GS = 0x1D;

    /** * data link escape */
    public static final byte DLE = 0x10;

    /** * End of transmission */
    public static final byte EOT = 0x04;

    /** * Enquiry character */
    public static final byte ENQ = 0x05;

    /** * Spaces */
    public static final byte SP = 0x20;

     

标签: 连接器xcd45t4k1p40016lf连接器2a振动变送器psxzdbpkgv2a1m传感器20320小间距连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台