IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android-USB通信 -> 正文阅读

[移动开发]Android-USB通信

Android-USB通信

本文记录下,Android平台上如何与USB设备进行通信。我这里使用的USB设备是一个USB加密设备(简称Ukey),通过与Ukey通信,对数据进行加密,提供一些加密算法。

USB API介绍

  • UsbManager:获得USB的状态,与连接的USB设备通信。
  • UsbDevice:USB设备的抽象,它包含了一个或多个的UsbInterface,而每个UsbInterface包含多个UsbEndpoint。Host与其通信,先打开UsbDeviceConnection,使用UsbRequest在一个端点(UsbEndpoint)发送和接受数据。
  • UsbDeviceConnection:host与device建立的连接,并在endpoint传输数据。
  • UsbEndpoint:endpoint是interface的通信信道。
  • UsbInterface : 定理设备的功能集,一个UsbDevice包含多个UsbInterface,每个UsbInterface都是独立的。
  • UsbRequest:usb请求包。可以在UsbDeviceConnection上异步传输数据。注意是只在异步通信时才会使用到它。
UsbManager常用方法说明
getDeviceList()获得设备列表,返回的是一个HashMap
hasPermission(UsbDevice device)判断你的应用程序是否有接入此USB设备的权限,如果有则返回真,否则返回false
openDevice(UsbDevice device)打开USB设备,以便向此USB设备发送和接受数据,返回一个关于此USB设备的连接
requestPermission(UsbDevice device, PendingIntent pi)向USB设备请求临时的接入权限
UsbDevice常用方法说明
getDeviceClass()返回此USB设备的类别,用一个整型来表示
getDeviceId()返回唯一标识此设备的ID号,也用一个整型来表示
getDeviceName()返回此设备的名称,用一个字符串来表示
getDeviceProtocol()返回此设备的协议类别,用一个整型来表示
getDeviceSubclass()返回此设备的子类别,用一个整型来表示
getVendorId()返回生产商ID
getProductId()返回产品ID
getInterfaceCount()返回此设备的接口数量
getInterface(int index)得到此设备的一个接口,返回一个UsbInterface
UsbDeviceConnection常用方法说明
bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)通过给定的endpoint来进行大量的数据传输,传输的方向取决于该节点的方向,buffer是要发送或接收的字节数组,length是该字节数组的长度。传输成功则返回所传输的字节数组的长度,失败则返回负数
controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout该方法通过0节点向此设备传输数据,传输的方向取决于请求的类别,如果requestType为USB_DIR_OUT则为写数据,USB_DIR_IN, 则为读数据
UsbEndpoint常用方法说明
getAddress()获得此节点的地址
getAttributes()获得此节点的属性
getDirection()获得此节点的数据传输方向
UsbInterface常用方法说明
getId()得到给接口的id号。
getInterfaceClass()得到该接口的类别
getInterfaceSubclass()得到该接口的子类
getInterfaceProtocol()得到该接口的协议类别。
getEndpointCount()获得关于此接口的节点数量
getEndpoint(int index)对于指定的index获得此接口的一个节点,返回一个UsbEndpoint

获取USB设备权限

  1. 首先在AndroidManifest.xml中添加权限
	<uses-feature
        android:name="android.hardware.usb.host"
        android:required="true"/>
    <uses-permission android:name="android.permission.MANAGE_USB"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.HARDWARE_TEST"
        tools:ignore="ProtectedPermissions" />

在标签中添加:

<intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data
    android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
    android:resource="@xml/device_USB" />

在res下创建xml名称的文件夹。
device_USB.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-device vendor-id="9840" product-id="1030"/>
</resources>
  1. 申请USB权限
 private static final String ACTION_USB_PERMISSION = "com.android.usb.USB_PERMISSION";


 private void getUsbPermission(UsbDevice mUSBDevice) {
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        registerReceiver(mUsbReceiver, filter);// 广播监听,监听USB设备插拔、权限
        usbManager.requestPermission(mUSBDevice, pendingIntent); // 该代码执行后,系统弹出一个对话框/等待权限
    }

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    unregisterReceiver(mUsbReceiver);
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false) && device.equals(device)) {
                        //授权成功后,进行USB设备操作
                        initUSB();
                    } else {
                        // 拒绝
                        Toast.makeText(MainActivity.this, "拒绝权限会造成与UKey通信失败!", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    };

初始化设备

  1. 获取USB设备
		UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        List<UsbDevice> usbDevices = new ArrayList<UsbDevice>();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            usbDevices.add(device);
            Log.e("USB_Test", "getDeviceList: " + device.getDeviceId());
        }
        device = usbDevices.get(0);// U口使用的是第一个设备节点,只获取第一个设备信息
  1. 获取设备功能节点
UsbInterface usbInterface = device.getInterface(0);
UsbEndpoint epBulkIn = usbInterface.getEndpoint(0);// 读信息
UsbEndpoint epBulkOut = usbInterface.getEndpoint(1);// 写入指令

f (usbInterface != null) {
    // open前判断连接权限
    if (usbManager.hasPermission(device)) {
        // 打开USB设备,以便向此USB设备发送和接受数据,返回一个关于此USB设备的连接
        usbDeviceConnection = usbManager.openDevice(device);
    }
    if (usbDeviceConnection != null && usbDeviceConnection.claimInterface(usbInterface, true)) {
        usbDeviceConnection = conn;
        if (usbDeviceConnection != null) {
            // android设备已经连接硬件设备
            Log.e("USB_Test", "android设备已经连接硬件设备.");
        }
    } else {
    
    }
}

USB交互

发送测试指令

 	private void sendToUsb(UsbEndpoint usbEpOut, UsbEndpoint usbEpIn) {
        byte[] buffer = new byte[320];
		// 0200050084000010   随机数
        buffer[0] = 0x02;
        buffer[1] = 0x00;
        buffer[2] = 0x05;
        buffer[3] = 0x00;
        buffer[4] = (byte) 0x84;
        buffer[5] = 0x00;
        buffer[6] = 0x00;
        buffer[7] = 0x10;

		int ret = -1;
        // 发送准备命令
        ret = usbDeviceConnection.bulkTransfer(usbEpOut, buffer, buffer.length, 5000);

        // 接收发送成功信息(相当于读取设备数据)
        byte[] receiveytes = new byte[320];// 根据设备实际情况写数据大小
        ret = usbDeviceConnection.bulkTransfer(usbEpIn, receiveytes, receiveytes.length, 10000);

        try {
            String strHex = DataUtils.getByteHexString(receiveytes);
            tv.setText(ret + "\n " + strHex);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

运行效果:
运行效果

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:47:45  更:2022-04-22 18:51:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 22:48:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码