硬件系列(六)--------------小票打印之无SDK打印

一、前言

硬件系列(五)-------------Android小票打印机连接 (已封装好,可直接使用)博文中,介绍了利用小票打印sdk进行小票打印,这个也是很久前写的了,也有很多同行的朋友需要sdk进行打印,只是碍于写那篇博文的时候是抽离出来的,很多同行要demo就没有,现在正好有台小票打印机在身边,就顺便做了一下总结,写了一些相关硬件的demo,都是打印机系列,这次demo会分享出来,保证可行,小票打印机可以支持很多品牌的打印,只要能获取到打印设备的pid和vid,就能进行小票打印了。不多说,开撸。

二、USB管理类

import android.annotation.SuppressLint;
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.util.Log;

import java.util.HashMap;
import java.util.Iterator;

/**
 * usb端口测试
 *
 * @author Freak
 * @date 2019/8/13.
 */
public class UsbAdmin {

    private static final String TAG = "UsbAdmin";
    private UsbManager mUsbManager;
    private UsbDevice mDevice;
    private UsbDeviceConnection mConnection;
    private UsbEndpoint mEndpointIntr;
    private PendingIntent mPermissionIntent = null;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    @SuppressLint("NewApi")
    private void setDevice(UsbDevice device) {
        if (device != null) {
            UsbInterface intf = null;
            UsbEndpoint ep = null;

            int interfaceCount = device.getInterfaceCount();
            Log.i(TAG, "InterfaceCount:" + interfaceCount);
            int j;

            mDevice = device;
            for (j = 0; j < interfaceCount; j++) {
                int i;

                intf = device.getInterface(j);
                Log.i(TAG, "接口是:" + j + "类是:" + intf.getInterfaceClass());
                if (intf.getInterfaceClass() == 7) {
                    int usbEndpointCount = intf.getEndpointCount();
                    for (i = 0; i < usbEndpointCount; i++) {
                        ep = intf.getEndpoint(i);
                        Log.i(TAG, "端点是:" + i + "方向是:" + ep.getDirection() + "类型是:" + ep.getType());
                        if (ep.getDirection() == 0 && ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                            Log.i(TAG, "接口是:" + j + "端点是:" + i);
                            break;
                        }
                    }
                    if (i != usbEndpointCount) {
                        break;
                    }
                }
            }

            if (j == interfaceCount) {
                Log.i(TAG, "没有打印机接口");
                return;
            }

            mEndpointIntr = ep;

            UsbDeviceConnection connection = mUsbManager.openDevice(device);

            if (connection != null && connection.claimInterface(intf, true)) {
                Log.i(TAG, "打开成功! ");
                Log.i(TAG, "connection " + connection);
                mConnection = connection;

            } else {
                Log.i(TAG, "打开失败! ");
                mConnection = null;
            }

        }
    }

    /**
     * 这是测试打开usb
     */
    @SuppressLint("NewApi")
    public void openUsb() {
        Log.i(TAG, "执行到这里1 ");
        if (mDevice != null) {
            Log.i(TAG, "执行到这里2 ");

            Log.i(TAG, "mDevice: " + mDevice.getDeviceId());

            setDevice(mDevice);

            if (mConnection == null) {
                HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
                Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

                while (deviceIterator.hasNext()) {
                    UsbDevice device = deviceIterator.next();
                    mUsbManager.requestPermission(device, mPermissionIntent);
                }
            }

        } else {
            Log.i(TAG, "执行到这里3");
            HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
            Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

            while (deviceIterator.hasNext()) {
                UsbDevice device = deviceIterator.next();
                Log.i(TAG, "执行到这里4" + device.getDeviceId());
                mUsbManager.requestPermission(device, mPermissionIntent);
            }
        }
    }

    @SuppressLint("NewApi")
    public void closeUsb() {
        if (mConnection != null) {
            mConnection.close();
            mConnection = null;
        }
    }

    public String getUsbStatus(boolean language) {
        if (mDevice == null) {
            if (language) {
                return "没有Usb设备!";
            } else {
                return "No Usb Device!";
            }
        }
        if (mConnection == null) {
            if (language) {
                return "Usb设备不是打印机!";
            } else {
                return "Usb device is not a printer!";
            }
        }
        if (language) {
            return "Usb打印机打开成功!";
        }
        return "Usb Printer Open success!";
    }

    /**
     * 打印连接的测试回馈
     *
     * @return
     */
    public boolean getUsbStatus() {
        if (mConnection == null) {
            return false;
        }
        return true;
    }

    /**
     * 发送信息 一是打印消息,切纸,打开钱箱等
     *
     * @param content
     * @return
     */
    @SuppressLint("NewApi")
    public boolean sendCommand(byte[] content) {
        boolean result;
        synchronized (this) {
            int len = -1;
            if (mConnection != null) {
                len = mConnection.bulkTransfer(mEndpointIntr, content, content.length, 10000);
            }

            if (len < 0) {
                result = false;
                Log.i(TAG, "发送失败! " + len);
            } else {
                result = true;
                Log.i(TAG, "发送" + len + "字节数据");
            }
        }
        return result;
    }

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {

                        if (device != null) {
                            //现在排除了标签打印机

                            Log.d(TAG, "其他设备的id " + device.getProductId());

//                            if (device.getProductId() != 22304) {
//                                setDevice(device);
//                            }

                            if (device.getProductId() != 1 && device.getProductId() != 46880 && device.getProductId() != 22304) {
                                setDevice(device);
                            }

                        } else {
                            closeUsb();
                            mDevice = device;
                        }
                    } else {
                        Log.d(TAG, "permission denied for device " + device);
                    }

                }

            }
        }
    };
    private static UsbAdmin usbAdmin;

    public static UsbAdmin getInstance(Context context) {
        if (usbAdmin != null) {
            return usbAdmin;
        } else {
            usbAdmin = new UsbAdmin(context);
            return usbAdmin;
        }
    }

    public UsbAdmin(Context context) {
        mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        context.registerReceiver(mUsbReceiver, filter);
    }
}

三、打印工具类

/**
 * 调用硬件工具类
 *
 * @author Freak
 * @date 2019/8/13.
 */

public class HardwareUtil {

    public static final byte[] PRINTF_CUT = {0x0a, 0x0a, 0x1d, 0x56, 0x01};
    public static final byte[] PUSH_CASH = {0x1b, 0x70, 0x00, 0x1e, (byte) 0xff, 0x00};

    public static final int TYPE_COLLECTION = 0;
    public static final int TYPE_WEB_ORDER = 1;
    public static final int TYPE_VIP_CARD = 2;
    public static final int TYPE_TRANSFER = 3;

    /**
     * 设备是否连接
     */
    public static boolean isConnected(UsbAdmin mUsbAdmin) {
        mUsbAdmin.openUsb();

        if (!mUsbAdmin.getUsbStatus()) {
            return false;
        } else {
            return true;
        }
    }


    /**
     * 是否能打印
     */
    public static boolean isPrintfData(String content, UsbAdmin mUsbAdmin) {

        boolean print = (boolean) ACache.get(App.getInstance().getApplicationContext()).getAsObject(Constants.WHETHER_PRINT);
        Log.d("HardwareUtil", "是否打印" + print);
        if (!print) {
            return false;
        }
        byte[] data = new byte[1024];
        try {
            String cmd = testFormat();
            data = cmd.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (mUsbAdmin.sendCommand(data) && mUsbAdmin.sendCommand(PRINTF_CUT)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 打开钱箱
     *
     * @param mUsbAdmin
     * @return
     */
    public static boolean pushCash(UsbAdmin mUsbAdmin) {
        boolean canPush = false;
        mUsbAdmin.openUsb();
        mUsbAdmin.getUsbStatus();
        if (mUsbAdmin.sendCommand(PUSH_CASH)) {
            canPush = true;
        } else {
            canPush = false;
        }
        return canPush;
    }


    /**
     * 测试格式
     */
    public static String testFormat() {
        String data = null;
        String time = DateUtil.getTime();
        data = "测试单据" +
                cmdEnter() +
                "------------------------------\n" +
                cmdEnter() +
                "收银员:1001\n" +
                "测试时间:  " + time + "\n" +
                "------------------------------\n" +
                cmdEnter();

        return data;
    }

    /**
     * 换行
     *
     * @return
     */
    public static String cmdEnter() {
        return new StringBuffer().append((char) 10).toString();
    }
}

四、调用方法

4.1、初始化

private UsbAdmin mUsbAdmin;
mUsbAdmin = UsbAdmin.getInstance(getActivity());

4.2、连接打印机

HardwareUtil.isConnected(mUsbAdmin);
//连接可能需要1秒时间,设置延时任务,更新连接状态
mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        mHandler.sendEmptyMessage(0);
    }
}, 2000);

handle是为了延迟一下更新连接状态,因为连接的时候需要一点时间。

4.3、断开打印机

mUsbAdmin.closeUsb();
mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        mHandler.sendEmptyMessage(1);
    }
}, 2000);

4.4、打印测试

HardwareUtil.isPrintfData("", mUsbAdmin);

五、分析

这个小票打印使用的是UsbManager进行usb设备的获取,需要一个USB权限com.android.example.USB_PERMISSION,无关设备没有这个权限就无法使用usb打印设备打印,也就找不到这个打印设备。

再初始化的时候,是创建了一个UsbAdmin对象,我们来看一下构造方法:

public UsbAdmin(Context context) {
    mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
    mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    context.registerReceiver(mUsbReceiver, filter);
}
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {

                        if (device != null) {
                            //现在排除了标签打印机

                            Log.d(TAG, "其他设备的id " + device.getProductId());

//                            if (device.getProductId() != 22304) {
//                                setDevice(device);
//                            }

                            if (device.getProductId() != 1 && device.getProductId() != 46880 && device.getProductId() != 22304) {
                                setDevice(device);
                            }

                        } else {
                            closeUsb();
                            mDevice = device;
                        }
                    } else {
                        Log.d(TAG, "permission denied for device " + device);
                    }

                }

            }
        }
    };

在openUsb方法中,每一个设备都进行了权限的请求:

mUsbManager.requestPermission(device, mPermissionIntent);

然后根据获取的设备去打印,打印效果如图所示:

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值