锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Android之USB打印

时间:2022-08-31 15:30:00 连接器xcd45t4k1p40016lf连接器2a振动变送器psxzdbpkgv2a1m传感器20320小间距连接器

文章目录

  • 前言
  • 一、效果图
  • 二、使用步骤
    • 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。 * 

* 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;

     

相关文章