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 host -> 正文阅读

[移动开发]Android usb host

当你的Android主机是处于USB主模式下,它充当USB主机,开启设备并列举出所有已连接的USB设备。这种模式在Android 3.1及以上的版本支持。

API预览

在开始开发USB Host之前,需要了解android.hardware.usb包下USB host 的API:

ClassDescription
UsbManager可以列举出USB设备,并和设备交互
UsbDevice表示已连接的USB设备,包含了访问设备标识信息的方法、接口和挂载点
UsbInterface表示设备接口,定义了一些列的功能函数。一个设备可以包含一个或多个接口
UsbEndPoint表示一个挂载点接口,定义了一个交互通道。一个接口可以包含一个或多个挂载点。通常都包含用于和USB设备交互输入输出的双向端点
UsbDeviceConnection表示到USB设备的一个基于端点通信的接口,这个类支持同步和异步数据的来回通讯
UsbRequest表示一个异步的,基于UsbDeviceConnection通讯的异步请求
UsbConstants定义了一些USB常量,与linux内核中的 Linux/usb/ch9.h中定义的一致

在USB设备交互的情况下,你需要用到所有的这些类(除了交互的时候,需要用到UsbRequest)。首先需要获取UsbManager对象来查询目标设备UsbDevice。当获得设备UsbDevice之后,你需要找到适当的UsbInterface以及该接口对应的UsbEndPoint,从而进行交互。一但拿到正确的端点,打开连接UsbDeviceConnection,以此和Usb设备进行交互。

Manifest文件的必要节点

下面的列表,列出了在使用Usb host的API之前,你所需要添加到Manifest文件中的东西:

由于不能确保所有的Android设备都支持USB host 的API , 我们可以在Manifest文件中加入 节点,来声明我们的应用需要android.hardware.usb.host 支持.

设置应用程序的最低支持的SDK版本为12或者更高. USB 主机模式的 API 在12以前的版本上不适用.

如果希望你的应用能够接收到USB设备挂在的通知,则需要在你的主Activity的android.hardware.usb.action.USB_DEVICE_ATTACHED过滤器中指定 和 节点对. 节点对应着一个外部XML 资源文件,这个资源文件定义了你想检测的设备的一些唯一标识信息.

在XML资源文件中,通过声明节点 来过滤你想要过滤的设备. 以下列表列出了 的 属性. 总的来说, 使用 vendor-id 和 product-id 来过滤指定的USB设备,使用 class, subclass 和 protocol 来过滤一组设备, 比如说大容量存储设备和数码相机. 你可以指定所有的属性或者一个都不指定.如果你什么属性都不设置,就将匹配所有的USB设备,当程序需要的时候,你可以这么指定:

vendor-id
product-id
class
subclass
protocol (device or interface)

该资源文件保存在 res/xml/ 目录下. 它的文件名(不包含.xml后缀名) 必须和 节点指定的名字一样. 文件的格式样式如下example:
Manifest文件 和资源文件
下面是一个简单的manifest文件及其对应的资源文件:

<manifest ...>
    <uses-feature android:name="android.hardware.usb.host" /> <uses-sdk android:minSdkVersion="12" />
    ...
    <application>
        <activity ...>
                ...
        <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_filter" />
        </activity>
    </application>
</manifest>

在上面的manifest文件下,对应的资源文件必须保存为 res/xml/device_filter.xml,并且使用特定的属性来过滤任何USB设备:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <usb-device product-id="4100" vendor-id="1204" />
   <usb-device product-id="4356" vendor-id="1204" />
   <usb-device product-id="22288" vendor-id="1155" />
   <usb-device product-id="0xAA97" vendor-id="0xAAAA" />
</resources>

代码实例

public class UsbHostTool {
    private final int USB_CONNECTED = 0;
    private final int USB_DISCONNECT = 1;
    private Context mContext = null;
    private static final String WK_ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    private UsbDevice mUsbDevice = null;
    private UsbDeviceConnection mDeviceConnection;
    private UsbEndpoint endPointForSendData;
    private UsbEndpoint endPointForUsb;
    //private UsbEndpoint endPointForHdmi;
    private UsbEndpoint endPointForGetData;
    //private UsbEndpoint endPointForMData;
    private int usbState = USB_DISCONNECT;
    private FiFoUsbStream fiFoUsbStream = null;


    private ExecutorService executorService = null;
    private ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor = null;

    private IUsbHostDataListner iUsbHostDataListner;
    private int interfaceCount = 0;
    private UsbInterface[] mInterfaceArray = new UsbInterface[5];
    private byte[] revUsbData = new byte[8 * 1024];
    private final int TIMEOUT = 200; //300

    public UsbHostTool(Context context, IUsbHostDataListner iUsbHostDataListner) {
        this.mContext = context;
        this.iUsbHostDataListner = iUsbHostDataListner;
        executorService = Executors.newScheduledThreadPool(5);
        mScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(5);
        usbDevicesInit(context);
    }

    /**
     * onCreate/onDestroy;onResume/onPause组合中注册和解绑
     */
    public void registerMyReceivers(Context mContext) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(WK_ACTION_USB_PERMISSION);
        mContext.registerReceiver(mUsbReceiver, filter);
    }

    /**
     * onCreate/onDestroy;onResume/onPause组合中注册和解绑
     */
    public void unregisterMyReceivers(Context mContext) {
        mContext.unregisterReceiver(mUsbReceiver);
    }


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

            WkLogTool.showLog("action=" + action);
            switch (action) {
                case WK_ACTION_USB_PERMISSION:
                    synchronized (this) {
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            WkLogTool.showLog("授权成功 ,再次请求链接usb");
                            findEndPoints(mUsbDevice); // 授权成功
                        } else {
                            WkLogTool.showLog("用户拒绝授权");
                        }
                    }
                    break;
                case UsbManager.ACTION_USB_DEVICE_DETACHED:
                    Observable.just(action)
                            .compose(RxjavaTool::toSimpleObservable)
                            .subscribe(value -> {
                                showMsg(mContext, "USB断开连接");
                                ((Activity) mContext).finish();
                            });

                    break;
                case UsbManager.ACTION_USB_DEVICE_ATTACHED:
                    Observable.just(action)
                            .compose(RxjavaTool::toSimpleObservable)
                            .subscribe(value -> {
                                showMsg(mContext, "USB已经连接");
                            });
                    break;
                default:
                    break;
            }
        }
    };

    private void usbDevicesInit(Context mContext) {
        WkLogTool.showLog("开始初始化 usb 设备----------------");
        if (usbState == USB_CONNECTED) {
            WkLogTool.showLog("usb 已经初始化了");
            return;
        }

        HashMap<String, UsbDevice> deviceList = getUsbManager(mContext).getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            int vid = device.getVendorId();
            if (vid == 0x0000
                    || vid == 0x04b4
                    || vid == 0x0951
                    || vid == 0x483
                    || vid == 0xAAAA) {
                mUsbDevice = device;
                WkLogTool.showLog("发现usb设备, vid=" + vid);
            }
        }

        boolean hasPermission = checkUsbPermission(mContext, mUsbDevice);

        if (mUsbDevice == null) {
            WkLogTool.showLog("mUsbDevice==null    lllllllll");
            return;
        }

        if (hasPermission) {
            WkLogTool.showLog("有权限,无需授权 ,直接去打开usb 连接");
            findEndPoints(mUsbDevice); // 初始化进去有权限 就直接打开
        } else {
            WkLogTool.showLog("usb没有权限,开始申请权限");
            PendingIntent permissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(WK_ACTION_USB_PERMISSION), 0);
            getUsbManager(mContext).requestPermission(mUsbDevice, permissionIntent);
        }
    }

    private UsbManager getUsbManager(Context mContext) {
        UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        if (manager == null) {
            WkLogTool.showLogError("UsbManager 获取失败!!!");
        }
        return manager;
    }

    private boolean checkUsbPermission(Context mContext, UsbDevice mUsbDevice) {
        if (mUsbDevice == null) {
            WkLogTool.showLog("mUsbDevicew为null------------------------------");
            return false;
        }
        return getUsbManager(mContext).hasPermission(mUsbDevice);
    }

    private void findEndPoints(UsbDevice mUsbDevice) {
        WkLogTool.showLog("开始 寻找usb节点----------------");
        int faceCount = mUsbDevice.getInterfaceCount();
        interfaceCount = faceCount;
        int pid = mUsbDevice.getProductId();
        WkLogTool.showLog("pid=" + pid + "    vid=" + mUsbDevice.getVendorId() + " 设备发现接口数量=" + faceCount);
        if (faceCount < 1) {
            WkLogTool.showLog("接口数量异常!!!!--------------------- " + faceCount);
            return;
        }

        for (int i = 0; i < faceCount; i++) {
            mInterfaceArray[i] = mUsbDevice.getInterface(i);
        }

        if (mInterfaceArray[0] == null) {
            WkLogTool.showLogError("usb 设备接口获取失败");
        } else {
            UsbDeviceConnection connection = getUsbManager(mContext).openDevice(mUsbDevice);
            mDeviceConnection = connection;
            if (connection == null) {
                WkLogTool.showLogError("usb connection 获取失败");
                return;
            }

            for (int i = 0; i < faceCount; i++) {
                boolean claimInterface = connection.claimInterface(mInterfaceArray[i], true);
                if (claimInterface) {
                    int endpointCount = mInterfaceArray[i].getEndpointCount();
                    for (int index = 0; index < endpointCount; index++) {
                        UsbEndpoint usbEndpoint = mInterfaceArray[i].getEndpoint(index);
                        int direction = usbEndpoint.getDirection();
                        int endPointNumber = usbEndpoint.getEndpointNumber();

                        if (direction == UsbConstants.USB_DIR_IN) {
                            switch (endPointNumber) {
                                case 0x05:
                                    //hdmi码流(瞄准镜)
                                    //endPointForHdmi = usbEndpoint;
                                    break;

                                case 0x08:
                                case 0x04:
                                    endPointForGetData = usbEndpoint;
                                    break;

                                case 0x06:
                                    //usb码流(主镜头)
                                    endPointForUsb = usbEndpoint;
                                    break;

                                case 0x03:
                                    //endPointForMData = usbEndpoint;
                                    break;
                                default:
                                    break;
                            }

                        } else if (direction == UsbConstants.USB_DIR_OUT) {
                            if (endPointNumber == 0x01) {
                                endPointForSendData = usbEndpoint;
                            }
                        }
                    }
                } else {
                    WkLogTool.showLogError("usb 连接打开接口失败 。 节点=" + i);
                }
            }// end for

            // usb链接成功建立了
            onConnectUsbSuccess();
        }
    }

    private void onConnectUsbSuccess() {
        usbState = USB_CONNECTED;
        fiFoUsbStream = new FiFoUsbStream();

        //接收 usb 数据
        new Thread(this::captureUsbStream).start();

        mScheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
            if (isSerialPortDataTimeOut()) { // 暂停 主动读取飞控数据(要读取)
                WkLogTool.showLog("灯变红 ,暂停主动接收 飞控信息 --------");
            } else {
                initCmdToGetFcsData(); // 为了获取飞控数据
            }
        }, 500, 300, TimeUnit.MILLISECONDS);


        mScheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
            if (isSerialPortDataTimeOut()) { // 暂停 主动读取飞控数据(要读取)
                WkLogTool.showLog("灯变红 ,暂停主动接收  图传质量等数据--------");
            } else {
                toGetDeviceInfo(); // 为了 当前频段 、图传带宽、自适应码流是否开启等
            }
        }, 500, 500, TimeUnit.MILLISECONDS);


        mScheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
            if (isSerialPortDataTimeOut()) { // 暂停 主动读取飞控数据(要读取)
                WkLogTool.showLog("灯变红 ,暂停主动接收  图传质量等数据--------");
            } else {
                toGetSignalQuality();// 为了读取链路是否断开等情况 、图传状态 、信号强度 、信号质量等
            }
        }, 0, 600, TimeUnit.MILLISECONDS);

        mScheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
            if (isSerialPortDataTimeOut()) {
                WkLogTool.showLog("灯变红 ,暂停主动接收  图传质量等数据--------");
            } else {
                queryAR8020Status();
            }
        }, 500, 200, TimeUnit.MILLISECONDS);

        // 开始接收 飞控信息
        startRevDataThread();

        // 开始寻找 usb 视频帧
        executorService.execute(() -> {
            try {
                WkLogTool.showLog("开始接收 寻找 usb 视频帧 " + isRunning);
                while (isRunning) {
                    if (fiFoUsbStream.buffer.length > 0) {
                        iUsbHostDataListner.toSearchUsbVideoFrame(fiFoUsbStream);
                    }
                    Thread.sleep(1);
                }
            } catch (Exception e) {
                WkLogTool.showLog("主码流发生异常=" + e.getMessage());
                e.printStackTrace();
            }
        });
    }

    private boolean isRunning = true;

    public void releaseUsbDeviceConnections() {
        isRunning = false;
        usbState = USB_DISCONNECT;
        WkLogTool.showLog("开始释放所有usb,status= " + usbState);
        for (int i = 0; i < interfaceCount; i++) {
            WkLogTool.showLog("释放usb接口" + i);
            if (mDeviceConnection != null) {
                mDeviceConnection.releaseInterface(mInterfaceArray[i]);
            }
        }
        for (int i = 0; i < interfaceCount; i++) {
            mInterfaceArray[i] = null;
        }
        if (mDeviceConnection != null) {
            mDeviceConnection.close();
            mDeviceConnection = null;
        }

        if (mScheduledThreadPoolExecutor != null) {
            mScheduledThreadPoolExecutor.shutdown();
        }

        mUsbDevice = null;
        executorService.shutdown();
        stopStatusQuery();
        WkLogTool.showLog("释放完成");
    }

    /***
     * 图传状态查询
     */
    private void queryAR8020Status() {
        int len = -1;
        byte[] data = new byte[8];
        Arrays.fill(data, (byte) 0x00);
        data[0] = 0x01;

        try {
            if (USB_CONNECTED == usbState) {
                byte[] protocolPacket = AirLinkProtocol.getUsbHostCmdPackToSend(0x11, (byte) 1, (byte) 0, data, 1);
                len = mDeviceConnection.bulkTransfer(endPointForSendData, protocolPacket, protocolPacket.length, 1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 图传心跳。 飞控数据一直会到图传的。 如果不发,就不会下发到app 。
     */
    private int initCmdToGetFcsData() {
        int len = -1;
        try {
            if (USB_CONNECTED == usbState) {
                if (mDeviceConnection != null) {
                    byte[] protocolPacket = AirLinkProtocol.getUsbHostCmdPackToSend(UsbHostConfig.KEY_0X85, (byte) 1, (byte) 0, null, 0);
                    len = mDeviceConnection.bulkTransfer(endPointForSendData, protocolPacket, protocolPacket.length, 1000);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /***
     * 切换 2.4G 和 5.8G
     */
    public void switch24and58(boolean is24Way) {
        try {
            if (USB_CONNECTED == usbState) {
                if (mDeviceConnection != null) {
                    int msgID = UsbHostConfig.KEY_0X22;
                    byte sumNum = 1; //一条数据分成几个包发送了
                    byte curNum = 0; // 当前包的顺序
                    byte[] payload = new byte[1]; // 数据段
                    payload[0] = is24Way ? (byte) 0x00 : (byte) 0x01;

                    int valueLen = payload.length; // payload的长度
                    byte[] protocolPacket = AirLinkProtocol.getUsbHostCmdPackToSend(msgID, sumNum, curNum, payload, valuelen);
                    WkLogTool.showLog("频道切换=" + MyByteBitTools.byte2HexStr(protocolPacket));
                    mDeviceConnection.bulkTransfer(endPointForSendData, protocolPacket, protocolPacket.length, 500);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * to get Device Info
     */
    private void toGetDeviceInfo() {
        int len = -1;
        try {
            if (USB_CONNECTED == usbState) {
                if (mDeviceConnection != null) {
                    int msgID = UsbHostConfig.KEY_0X19;
                    byte sumNum = 1; //一条数据分成几个包发送了
                    byte curNum = 0; // 当前包的顺序
                    byte[] payload = null; // 数据段
                    int valuelen = payload == null ? 0 : payload.length; // payload的长度
                    byte[] protocolPacket = AirLinkProtocol.getUsbHostCmdPackToSend(msgID, sumNum, curNum, payload, valuelen);
                    WkLogTool.showLog("为了读取0x19信息----------->" + MyByteBitTools.byte2HexStr(protocolPacket));
                    len = mDeviceConnection.bulkTransfer(endPointForSendData, protocolPacket, protocolPacket.length, 1000);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * to get 模组地面端状态信息
     */
    private void toGetSignalQuality() {
        int len = -1;
        try {
            if (USB_CONNECTED == usbState) {
                if (mDeviceConnection != null) {
                    int msgID = UsbHostConfig.KEY_0X82;
                    byte sumNum = 1; //一条数据分成几个包发送了
                    byte curNum = 0; // 当前包的顺序
                    byte[] payload = null; // 数据段
                    int valuelen = payload == null ? 0 : payload.length; // payload的长度
                    byte[] protocolPacket = AirLinkProtocol.getUsbHostCmdPackToSend(msgID, sumNum, curNum, payload, valuelen);
                    //WkLogTool.showLog("为了读取0x82信息----------->"+MyByteBitTools.byte2HexStr(protocolPacket));
                    len = mDeviceConnection.bulkTransfer(endPointForSendData, protocolPacket, protocolPacket.length, 1000);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean isSerialPortDataTimeOut() {
        return false;
    }

    /**
     * 循环获取来自USB的数据
     */
    private void captureUsbStream() {
        WkLogTool.showLog("开始接收 usb 数据--------" + usbState);
        int dataLen = 0;
        while (USB_CONNECTED == usbState) {
            try {

                if (isSerialPortDataTimeOut()) {  // 暂停 接收usb视频
                    // 串口数据接收超时,板子变红了。
                    Thread.sleep(100);
                    WkLogTool.showLog("灯变红 ,暂停接收 usb 数据--------");
                } else {
                    dataLen = mDeviceConnection.bulkTransfer(endPointForUsb, revUsbData, revUsbData.length, TIMEOUT);

                    boolean isError = dataLen < 200;
                    if (isError) {
                        byte[] testData = dataLen == -1 ? null : WkByteBitTools.subBytes(revUsbData, 0, 30);
                        WkLogTool.showLog("testData= " + MyByteBitTools.byte2HexStr(testData));
                    }

                    if (dataLen > 0) {
                        WkLogTool.showLog("usb数据接收  " + "   " + revUsbData.length);
                        if (fiFoUsbStream != null) {
                            fiFoUsbStream.FiFoWrite(revUsbData, dataLen);
                        }
                    } else {
                        WkLogTool.showLog("usb数据接收为(异常)  " + dataLen + "   " + revUsbData.length);
                    }
                }
            } catch (Exception e) {
                WkLogTool.showLogError("接收USB数据异常," + e.getMessage());
            }
        }
    }


    /**
     * 接收信息字节
     */
    private byte[] mReceiveBytes = new byte[512];

    public void startRevDataThread() {
        executorService.execute(() -> {
            try {
                int len = -1;
                WkLogTool.showLog("开始接收 飞控数据 " + isRunning);
                while (isRunning) {
                    if (USB_CONNECTED == usbState && endPointForGetData != null) {

                        if (isSerialPortDataTimeOut()) { // 暂停接收飞控数据
                            WkLogTool.showLog("灯变红 ,暂停被动接收 飞控 数据--------");
                            Thread.sleep(100);
                        } else {
                            len = mDeviceConnection.bulkTransfer(endPointForGetData, mReceiveBytes, mReceiveBytes.length, TIMEOUT);
                            if (len >= 10) {
                                // msgID 占用两个byte , [2] 、[3]
                                int msgId = ((mReceiveBytes[3] & 0x0FF) << 8) + (mReceiveBytes[2] & 0x0FF);

                                switch (msgId) {
                                    case UsbHostConfig.KEY_0X85:
                                        if (len > 10) {
                                            //  0XFF 0X5A 是固定头部
                                            if (mReceiveBytes[0] == (byte) 0xFF && mReceiveBytes[1] == (byte) 0x5A) {
                                                // lengh 占用两个byte  , [6]  、[7]
                                                int userDataLen = ((mReceiveBytes[7] & 0x0FF) << 8) + (mReceiveBytes[6] & 0x0FF);
                                                if (userDataLen > 0 && userDataLen < len) {
                                                    byte[] userDataArray = new byte[userDataLen];
                                                    // 头部格式 占用了10个 byte ,数据段是从第11个byte 开始读取
                                                    System.arraycopy(mReceiveBytes, 10, userDataArray, 0, userDataLen);
                                                    if (isRunning) {
                                                        iUsbHostDataListner.onDataRev(userDataArray);
                                                    }

                                                }
                                            }
                                        }
                                        break;
                                    case UsbHostConfig.KEY_0X19:
                                        if (isRunning) {
                                            processOx19(mReceiveBytes, len);
                                        }
                                        break;
                                    case UsbHostConfig.KEY_0X82:
                                        if (isRunning) {
                                            process0x82(mReceiveBytes, len);
                                        }
                                        break;

                                    default:
                                        break;
                                }

                            } else {
                                WkLogTool.showLog("飞控 数据接收为(异常) len= " + len);
                            }
                        }


                    } else {
                        WkLogTool.showLog("飞控 节点异常 ,或者数据通道还未未连接  ");
                        Thread.sleep(100);
                    }
                }  // end while
            } catch (Exception e) {
                WkLogTool.showLogError("接收 飞控 数据异常," + e.getMessage());
                e.printStackTrace();
            }
        });
    }


    private void processOx19(byte[] mReceiveBytes, int len) {
        if (mReceiveBytes[0] == (byte) 0xFF && mReceiveBytes[1] == (byte) 0x5A) {
            int userDataLen = ((mReceiveBytes[7] & 0x0FF) << 8) + (mReceiveBytes[6] & 0x0FF);
            if (userDataLen > 0 && userDataLen < len) {
                byte[] userDataArray = new byte[userDataLen];
                System.arraycopy(mReceiveBytes, 10, userDataArray, 0, userDataLen);
                int band = userDataArray[1];
                //01是2.4G,02是5.8G
                if (iUsbHostDataListner != null) {
                    if (band == 1) {
                        iUsbHostDataListner.onReceiveSignType("2.4G");
                    } else if (band == 2) {
                        iUsbHostDataListner.onReceiveSignType("5.8G");
                    }
                }
            }
        }
    }


    private void process0x82(byte[] mReceiveBytes, int len) {
        if (mReceiveBytes[0] == (byte) 0xFF && mReceiveBytes[1] == (byte) 0x5A) {
            int userDataLen = ((mReceiveBytes[7] & 0x0FF) << 8) + (mReceiveBytes[6] & 0x0FF);
            if (userDataLen > 0 && userDataLen < len) {
                byte[] userDataArray = new byte[userDataLen];
                System.arraycopy(mReceiveBytes, 10, userDataArray, 0, userDataLen);
                int groundSign= userDataArray[3];
                //天空端信号质量(该值必须是模块已连接成功才有效,取值范围 0-100,值越大,信号越好)
                int airSign = userDataArray[4];
                if (iUsbHostDataListner != null) {
                    iUsbHostDataListner.onReceiveHdSingQuality(airSign);
                    iUsbHostDataListner.onReceiveRcSignQuality(groundSign);
                }
            }
        }
    }

    private void showMsg(Context context, String str) {
        Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
    }

    public void setVisible(boolean isVisible) {
        if (fiFoUsbStream != null) {
            fiFoUsbStream.setVisible(isVisible);
        }
    }

    private void stopStatusQuery() {
        int len = -1;
        byte[] data = new byte[8];
        Arrays.fill(data, (byte) 0x00);
        data[0] = 0x11;
        data[1] = 0x01;
        data[2] = 0x00;

        try {
            if (USB_CONNECTED == usbState) {
                len = mDeviceConnection.bulkTransfer(endPointForSendData, data, 3, 1000);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 00:09:15  更:2021-07-24 00:09:30 
 
开发: 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年5日历 -2024/5/2 4:53:01-

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