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连接器
静态注册:
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