zoukankan      html  css  js  c++  java
  • 【转】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();
            }
        }
    }
  • 相关阅读:
    【xamarin + MvvmCross 从零开始】一、环境安装
    .NET微服务从0到1:服务容错(Polly)
    .NET微服务从0到1:服务注册与发现(Consul)
    .NET微服务从0到1:API网关(Ocelot)
    .NET Core之单元测试(四):Fluent Assertions的使用
    .NET Core之单元测试(三):Mock框架Moq的使用
    .NET Core之单元测试(二):使用内存数据库处理单元测试中的数据库依赖
    .NET Core之单元测试(一):入门
    win+navicat
    JDBC介绍和Mybatis运行原理及事务处理
  • 原文地址:https://www.cnblogs.com/tc310/p/8510657.html
Copyright © 2011-2022 走看看