【转】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();
        }
    }
}

原文地址:https://www.cnblogs.com/tc310/p/8510657.html

时间: 2024-08-03 06:05:19

【转】Android打印机--没有设备驱动sdk,自己实现USB打印功能的相关文章

USB设备驱动开发之远程访问USB设备(一)

By Fanxiushu 2016 05-15  转载或引用本文,请注明原始作者. 使用过vmware的人都应该知道,vmware虚拟机有这样的一个功能, 当在宿主机上插入一个USB设备的时候,通过设置,可以在vmware的虚拟机系统里边能访问到这个USB设备, 而且访问这个USB设备,就跟真的把这个USB设备插入到这个虚拟系统中一样,跟真实的几乎没任何区别. 再看一种情况,假设有两台机器C和S,C 机器是你正在使用的机器, S机器在远端,你只能通过远程控制S. S机器的配置和功能都很强大,大部

USB设备驱动开发之远程访问USB设备(二 USB设备虚拟端)

By Fanxiushu 2016-05-22 转载或引用请注明原始作者 接上文, 在处理好USB数据采集端的问题之后,接下来进入核心的部分,虚拟USB设备端的开发工作. 上文简单介绍过,需要开发虚拟总线驱动来模拟USB设备. 所谓虚拟总线驱动,就是安装于System系统设备下的一个驱动,由PnP管理器创建出一个虚拟的总线PDO设备, 我们的虚拟总线驱动Attach到这个PDO上,形成一个FDO功能设备驱动, 然后在我们的驱动中,根据需要创建出若干个 Child PDO设备, 这些 Child

基于Android移植IIC设备驱动笔记

我是从2015.7.23开始移植这个驱动程序的,经过在网上查找资料,决定利用linux下I2C驱动体系结构来完成驱动移植 整个步骤是根据http://blog.csdn.net/rickbeyond/article/details/7838313这个大神的博客开始的,于是我的苦逼坑死我之路从此开始.... 第一天下午就卡在了第三步,即对Android.mk的编译上,刚开始是报如下错误 make: *** No rule to make target `/iic.c', needed by `ou

Android 开发之 ---- 底层驱动开发(一)

驱动概述 说到 Android 驱动是离不开 Linux 驱动的.Android 内核采用的是 Linux2.6 内核 (最近Linux 3.3 已经包含了一些 Android 代码).但 Android 并没有完全照搬 Linux 系统内核,除了对Linux 进行部分修正,还增加了不少内容.android 驱动 主要分两种类型:Android 专用驱动 和 Android 使用的设备驱动(linux). Android 专有驱动程序: 1)Android Ashmem 匿名共享内存: 为用户空

Linux设备驱动核心理论(三)

10.中断与时钟 10.1 中断与定时器 所谓中断是指CPU在执行程序的过程中,出现了某些突发事件急待处理,CPU必须暂停执行当前程序,转去处理突发事件,处理完毕后CPU又返回原程序被中断的位置并继续执行. 根据中断的来源,中断可分为内部中断和外部中断,内部中断的中断来源来自CPU内部(软件中断.溢出.除法错误等,例如,操作系统从用户态切换到内核态需借助CPU内部的软件中断),外部中断的中断来源来自CPU外部,由外设提出请求. 根据中断是否可以屏蔽分为可屏蔽中断与不屏蔽中断(NMI),可屏蔽中断

USB设备驱动架构

1  USB设备驱动架构 这里说的USB设备驱动指的是从主机角度来看,怎样访问被插入的USB设备,而不是指USB设备内部本身运行的固件程序.Linux内核中实现了几类通用的USB设备驱动,主要包括下面几类: (1)音频设备类  (2)通信设备类  (3)HID(人机接口)设备类  (4)显示设备类  (5)海量存储设备类  (6)电源设备类  (7)打印设备类 一般的通用Linux设备(如U盘.USB鼠标.USB键盘等)都不需要工程师再编写驱动,而工程师需要编写的是特定厂商.特定芯片的驱动,而且

Linux设备驱动框架设计

引子 Linux操作系统的一大优势就是支持数以万计的芯片设备,大大小小的芯片厂商工程师都在积极地向Linux kernel提交设备驱动代码.能让这个目标得以实现,这背后隐藏着一个看不见的技术优势:Linux内核提供了一套易于扩展和维护的设备驱动框架.Linux内核本身提供一套设备驱动模型,此模型提供了Linux内核对设备的一般性抽象描述,包括设备的电源管理.对象生命周期管理.用户空间呈现等等.在设备模型的帮助下,设备驱动开发工程师从设备的一般性抽象中解脱出来.但是每个设备的具体功能实现还需要大量

Android 无线调试设备,无需Root方式

Android 真机设备调试,有事无法使用USB调试,或者用USB调试太麻烦,这时就需要使用无线调试 这种方式了. 无限调试分Root和非Root两种,市面上的无线ADB调试APP ,基本都是需要Root权限的,这就使没有Root的设备无法使用无线调试,进而需要使用非Root无限调试方法,废话不多说,下面介绍具体的方式. 准备工作 1.首先使用USB连接设备,并打开开发者模式的调试开关(通用调试方式,具体使用方法不赘述) 2.打开终端命令(Windows键+R,输入CMD ,回车) 3.输入 a

乾坤合一~Linux设备驱动之USB主机和设备驱动

如果不能陪你到最后 是否后悔当初我们牵手 如果当初没能遇见你 现在的我 在哪里逗留 所有的爱都是冒险 那就心甘情愿 等待我们一生中 所有悬念 我一往情深的恋人 她是我的爱人 她给我的爱就像是 带着露水的清晨 我多想给她我的真 我心疼的爱人 我愿为她守候寂寞 就像这夜晚 深沉 这一章从主机侧角度看到的USB 主机控制器驱动和设备驱动从主机侧的角度而言,需要编写的USB 驱动程序包括主机控制器驱动和设备驱动两类,USB 主机控制器驱动程序控制插入其中的USB 设备,而USB 设备驱动程序控制该设备如