USB

android usb OTG

2020-04-14  本文已影响0人  xuefeng_apple

本文主要介绍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

上一篇下一篇

猜你喜欢

热点阅读