android usb OTG

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

静态注册:
//www.greatytc.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
//www.greatytc.com/p/59db6b004f22
//www.greatytc.com/p/3dc561555f12

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容