Android打印机--没有设备驱动sdk,自己实现USB打印功能

Posted tc310

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android打印机--没有设备驱动sdk,自己实现USB打印功能相关的知识,希望对你有一定的参考价值。

原文:http://blog.csdn.net/johnwcheung/article/details/71576833

android下的设备调试,如果设备提供了驱动,按照厂家的驱动调试即可;设备未提供驱动,只能按照通用的方法进行调试。

对于智能POS、收银机以及其他打印设备,如果厂商不提供打印相关sdk,那么打印功能怎么实现呢?其实我们可以基于USB通信机制,自己去实现打印驱动。

整个实现流程如下

  1. 初始化打印机:首先要获取USB管理器;其次要注册监听USB设备插拔变化和请求权限的广播;最后列出所有的USB设备,并且都请求获取USB权限;

  2. 实现这个广播接收器:当接收到请求权限的广播时,获取USB设备的引用,android系统会询问你是否允许设备访问,默认为false;当允许了访问之后,会判断USB的引用是否为null, 如果不为空,说明该设备可以连接,否则提示设备拒绝访问;如果接收到已连接的打印设备移除的广播,则要关闭本次连接。

  3. 对于获得权限可使用的USB,我们将获取设备的功能集(UsbInterface)和通信通道(UsbEndpoint),然后创建host与device的连接用来传输数据。

  4. 最后,我们在需要打印的地方调用上面封装好的打印方法,就可以发送指令来控制已经建立连接的打印机了。

USB打印机实现

/**
 * USB打印机
 * Created by john on 17-5-10.
 */

public class USBPrinter {

    private static final String ACTION_USB_PERMISSION = "com.usb.printer.USB_PERMISSION";

    private static USBPrinter mInstance;

    private Context mContext;
    private UsbDevice mUsbDevice;
    private PendingIntent mPermissionIntent;
    private UsbManager mUsbManager;
    private UsbDeviceConnection mUsbDeviceConnection;

    private final BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        mUsbDevice = usbDevice;
                    } else {
                        Toast.makeText(context, "Permission denied for device " + usbDevice, Toast.LENGTH_SHORT).show();
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                if (mUsbDevice != null) {
                    Toast.makeText(context, "Device closed", Toast.LENGTH_SHORT).show();
                    if (mUsbDeviceConnection != null) {
                        mUsbDeviceConnection.close();
                    }
                }
            }
        }
    };

    private USBPrinter() {

    }

    public static USBPrinter getInstance() {
        if (mInstance == null) {
            mInstance = new USBPrinter();
        }
        return mInstance;
    }

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

    /**
     * 销毁打印机持有的对象
     */
    public static void destroyPrinter() {
        getInstance().destroy();
    }

    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);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        mContext.registerReceiver(mUsbDeviceReceiver, filter);

        // 列出所有的USB设备,并且都请求获取USB权限
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();

        for (UsbDevice device : deviceList.values()) {
            mUsbManager.requestPermission(device, mPermissionIntent);
        }
    }

    private void destroy() {
        mContext.unregisterReceiver(mUsbDeviceReceiver);

        if (mUsbDeviceConnection != null) {
            mUsbDeviceConnection.close();
            mUsbDeviceConnection = null;
        }

        mContext = null;
        mUsbManager = null;
    }

    /**
     * 打印方法
     * @param msg
     */
    public void print(String msg) {
        final String printData = msg;
        if (mUsbDevice != null) {
            UsbInterface usbInterface = mUsbDevice.getInterface(0);
            for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
                final UsbEndpoint ep = usbInterface.getEndpoint(i);
                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                    if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                        mUsbDeviceConnection = mUsbManager.openDevice(mUsbDevice);
                        if (mUsbDeviceConnection != null) {
                            Toast.makeText(mContext, "Device connected", Toast.LENGTH_SHORT).show();
                            mUsbDeviceConnection.claimInterface(usbInterface, true);
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    byte[] bytes = printData.getBytes();
                                    int b = mUsbDeviceConnection.bulkTransfer(ep, bytes, bytes.length, 100000);
                                    Log.i("Return Status", "b-->" + b);
                                }
                            }).start();

                            mUsbDeviceConnection.releaseInterface(usbInterface);
                            break;
                        }
                    }
                }
            }
        } else {
            Toast.makeText(mContext, "No available USB print device", Toast.LENGTH_SHORT).show();
        }
    }
}

以上是关于Android打印机--没有设备驱动sdk,自己实现USB打印功能的主要内容,如果未能解决你的问题,请参考以下文章

Android 可穿戴设备可以与 iOS 一起使用,通过 BLE 连接吗?有没有可用的SDK?

Android - 打印完整的异常回溯到日志

“Maps SDK for Android v.3.0.0 BETA”能否在没有 Google Play 服务的设备上运行?

Maps SDK for Android v.3.0.0 BETA "是否可以在没有Google Play服务的设备上运行?

Flutter设置:将android Sdk从设备转移到另一个

尝试使用Android Brother Sdk打印无线时,ERROR_WRONG_LABEL用于标签打印机