美文网首页USB
android usb OTG

android usb OTG

作者: xuefeng_apple | 来源:发表于2020-04-14 19:24 被阅读0次

    本文主要介绍USB host 模式:

    图片.png

    主要类:frameworks/base/core/java/android/hardware/usb/
    1:UsbManager.java 不用多说,对应的是Usb的管理类
    2:UsbDevice.java Usb设备绑定上,肯定要拿到对应的设备吧
    3:UsbInterface.java Usb对应的接口,通过接口拿到内部匹配Usbpoint
    4:UsbEndPoint.java Usb通信数据的传输主要其实就是通过这个类来进行的
    5:UsbDeviceConnection Usb连接器

    静态注册:
    https://www.jianshu.com/p/2faf007bd262

    CODE:
    通信主要就是调用这些API:UsbManager->UsbDevice->UsbInterface->UsbEndpoint->UsbDeviceConnection

    UsbInterface usbInterface = usbDevice.getInterface(1);
    UsbEndpoint inEndpoint = usbInterface.getEndpoint(0);
    UsbEndpoint outEndpoint = usbInterface.getEndpoint(1);
    UsbDeviceConnection connection = usbManager.openDevice(usbDevice);
    connection.claimInterface(usbInterface, true);
    
    sendString = "0xa5";
    sendBytes = HexString2Bytes(sendString);            
    int out = connection.bulkTransfer(outEndpoint, sendBytes, sendBytes.length, 5000);
    displayToast("发送:"+out+" # "+sendString+" # "+sendBytes);
    
    receiveBytes = new byte[32];
    int in = connection.bulkTransfer(inEndpoint, receiveBytes, receiveBytes.length, 10000);
    receiveString = Bytes2HexString(receiveBytes);
    displayToast("应答:"+in+" # "+receiveString+" # "+receiveBytes.length);   
    
    

    控制,中断,批量,同步, 是usb 四种传输模式
    bulkTransfer:批量模式
    ①in表示输入事务处理:USB主机从总线上某个USB设备上接收数据包;
    ②out表示输出事务处理:USB主机把一个数据包输出到总线上某个USB设备的接收过程

    说明 getParcelableExtra():
    1-Intent获取: 当在startActivity中传入一个隐式Intent时,首先通过对Intent解析,决定启动哪一个Activity

    2-信息传递:获取该Intent中的数据和动作,intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) 中的UsbManager.EXTRA_DEVICE就是存储在该Intent的extras bundle中的USB设备信息

    3-Parcelable意义:Parcelable属于Android编程中进程间通信(IPC)的一种机制,在两个Activity间传递简单的数据如String,可以直接通过intent.putExtra(String,s);在两个Activity间传递类对象,则需要通过Parcelable接口

    4-Parcelable的原理:将要传递的类内的属性分解为存储在Parcel中的基本类型,而这些类型是可以跨进程边界封送的;使用时将要传递类直接implements Parcelable即可实现接口类


    图片.png

    举例:读取U盘

    读取设备:

    public void readDeviceList() {
            UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
            returnMsg("开始去读Otg设备");
            storageDevices = UsbMassStorageDevice.getMassStorageDevices(mContext);
            mPendingIntent =PendingIntent.getBroadcast(mContext,0,new Intent(ACTION_USB_PERMISSION),0);
            if (storageDevices.length == 0) {
                returnMsg("没有检测到U盘s");
                return;
            }
            for (UsbMassStorageDevice device : storageDevices){
                if (usbManager.hasPermission(device.getUsbDevice())){
                    returnMsg("检测到有权限,延迟1秒开始读取....");
                    try {
                        Thread.sleep(1000 );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    readDevice(device);
                }else {
                    returnMsg("检测到有设备,但是没有权限,申请权限....");
                    usbManager.requestPermission(device.getUsbDevice(),mPendingIntent);
                }
            }
        }
    

    读取设备文件信息:

    private void readDevice(UsbMassStorageDevice device) {
            try {
                device.init();
                Partition partition = device.getPartitions().get(0);
                Log.i(TAG,"------------partition---------");
                Log.i(TAG,"VolumnLobel:"+partition.getVolumeLabel());
                Log.i(TAG,"blockSize:"+partition.getBlockSize()+"");
                FileSystem currentFs = partition.getFileSystem();
                Log.i(TAG,"------------FileSystem---------");
                UsbFile root = currentFs.getRootDirectory();
                String deviceName = currentFs.getVolumeLabel();
                Log.i(TAG,"volumnLable:"+deviceName);
                Log.i(TAG,"chunkSize:"+currentFs.getChunkSize());
                Log.i(TAG,"freeSize:"+currentFs.getFreeSpace());
                Log.i(TAG,"OccupiedSpcace:"+currentFs.getOccupiedSpace());
                Log.i(TAG,"capacity"+currentFs.getCapacity());
                Log.i(TAG,"rootFile:"+root.toString());
                returnMsg("正在读取U盘" + deviceName);
                readFile(root);
            } catch (IOException e) {
                e.printStackTrace();
                returnMsg("读取失败:"+e.getMessage());
            }finally {
            }
        }
    

    读取文件:

    private void readFile(UsbFile root){
            ArrayList<UsbFile> mUsbFiles = new ArrayList<>();
            try {
                for (UsbFile file: root.listFiles()){
                    Log.i(TAG,file.getName());
                    mUsbFiles.add(file);
                }
                Collections.sort(mUsbFiles, new Comparator<UsbFile>() {//简单排序 文件夹在前 文件在后
                    @Override
                    public int compare(UsbFile oFile1, UsbFile oFile2) {
                        if (oFile1.isDirectory()) return -1;
                        else return 1;
                    }
                });
                if (broadcastListener !=null){
                    broadcastListener.updateUsbFile(mUsbFiles);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
    

    参考开源:
    https://github.com/magnusja/libaums

    备注: 其他方式读取U盘(sdcard的形式来读你的U盘设备)
    {REF:https://blog.csdn.net/qq_29924041/article/details/80141514}

    /base/services/core/java/com/android/server/MountService.java
    /base/core/java/android/os/storage/VolumeInfo.java
    /base/core/java/android/os/storage/StorageManager.java

    VolumeInfo判断挂载过程和卸载过程:

    public class UsbReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(VolumeInfo.ACTION_USB_DEVICE_ATTACHED)) {
                Log.d("action===", "装载");
            } else if (action.equals(VolumeInfo.ACTION_USB_DEVICE_DETACHED)) {
                Log.d("action===", "卸载USB");
                Toast.makeText(context, "USB设备移除", Toast.LENGTH_SHORT).show();
                System.exit(0);
            } else if (action.equals(VolumeInfo.ACTION_VOLUME_STATE_CHANGED)) {
                int intExtra = intent.getIntExtra(VolumeInfo.EXTRA_VOLUME_STATE, VolumeInfo.STATE_UNMOUNTED);
                if (intExtra == VolumeInfo.STATE_MOUNTED) {
                    
                            Toast.makeText(UiUtils.getContext(), "发现USB设备", Toast.LENGTH_LONG).show()
                }
            }
        }
    }
    
    public class VolumeInfo {
        /**
         * U盘挂载类型  插入U盘 STATE_UNMOUNTED->STATE_MOUNTED;拔出U盘  STATE_EJECTING->STATE_UNMOUNTED->STATE_BAD_REMOVAL
         */
        //卸载
        public static final int STATE_UNMOUNTED = 0;
        //状态监测
        public static final int STATE_CHECKING = 1;
        //挂载完成
        public static final int STATE_MOUNTED = 2;
        //只读
        public static final int STATE_MOUNTED_READ_ONLY = 3;
        //格式化
        public static final int STATE_FORMATTING = 4;
        //开始移除
        public static final int STATE_EJECTING = 5;
        //无法挂载
        public static final int STATE_UNMOUNTABLE = 6;
        //删除
        public static final int STATE_REMOVED = 7;
        //移除完成
        public static final int STATE_BAD_REMOVAL = 8;
        /**
         * 接受广播key
         */
        public static final String ACTION_VOLUME_STATE_CHANGED = "android.os.storage.action.VOLUME_STATE_CHANGED";
        public static final String EXTRA_VOLUME_ID = "android.os.storage.extra.VOLUME_ID";
        public static final String EXTRA_VOLUME_STATE = "android.os.storage.extra.VOLUME_STATE";
        /**
         * 刚挂载和关闭
         */
        public static final String ACTION_USB_DEVICE_ATTACHED= "android.hardware.usb.action.USB_DEVICE_ATTACHED";
        public static final String ACTION_USB_DEVICE_DETACHED= "android.hardware.usb.action.USB_DEVICE_DETACHED";
    }
    

    REF:
    https://www.cnblogs.com/DreamRecorder/p/9213709.html
    https://blog.csdn.net/elsa_rong/article/details/47005129
    https://www.jianshu.com/p/59db6b004f22
    https://www.jianshu.com/p/3dc561555f12

    相关文章

      网友评论

        本文标题:android usb OTG

        本文链接:https://www.haomeiwen.com/subject/lkqxvhtx.html