前言

还是我实习的时候,遇到个要求说要支持 USB,当时找了很多博客,最后这篇文章帮我解决了问题,想想自己也没有其他要补充的,就转载一下吧!

这篇博客用的第三方库只支持 FAT32 格式的 U盘,如果时其他格式的话就有点麻烦了,毕竟现在这个格式都用的不多了,可以参考下面这篇博客写的东西,利用反射获得 U盘的实际路径进行操作:

Android-USB-OTG-读写U盘文件

原文

Android 基于libaums实现读写U盘文件

本文主要介绍利用libaums在android上实现Android端读写U盘的功能,并将其进行了封装,写了个工具类,方便大家参考。

准备工作

  • 在build.gradle文件中引用libaums:

    compile ‘com.github.mjdev:libaums:+’

  • 在AndroidManifest.xml中添加权限:

    <uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” /> <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” /> <uses-permission android:name=”android.hardware.usb.host” android:required=”false”/> <uses-feature android:name=”android.hardware.usb.host” android:required=”true” />

代码

USBBroadCastReceiver

USBBroadCastReceiver用于监听U盘的插拔,代码如下:

/*** Author : BlackHao* Time : 2018/5/10 10:07* Description : USB 广播* Logs :*/public class USBBroadCastReceiver extends BroadcastReceiver {private UsbListener usbListener;public static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();switch (action) {case ACTION_USB_PERMISSION://接受到自定义广播UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {//允许权限申请if (usbDevice != null) {//回调if (usbListener != null) {usbListener.getReadUsbPermission(usbDevice);}}} else {if (usbListener != null) {usbListener.failedReadUsb(usbDevice);}}break;case UsbManager.ACTION_USB_DEVICE_ATTACHED://接收到存储设备插入广播UsbDevice device_add = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device_add != null) {if (usbListener != null) {usbListener.insertUsb(device_add);}}break;case UsbManager.ACTION_USB_DEVICE_DETACHED://接收到存储设备拔出广播UsbDevice device_remove = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device_remove != null) {if (usbListener != null) {usbListener.removeUsb(device_remove);}}break;}}public void setUsbListener(UsbListener usbListener) {this.usbListener = usbListener;}/*** USB 操作监听*/public interface UsbListener {//USB 插入void insertUsb(UsbDevice device_add);//USB 移除void removeUsb(UsbDevice device_remove);//获取读取USB权限void getReadUsbPermission(UsbDevice usbDevice);//读取USB信息失败void failedReadUsb(UsbDevice usbDevice);}
}

UsbHelper

UsbHelper是关键的部分,封装了所有的USB文件操作,包括注册/注销USBBroadCastReceiver,获取U盘文件列表,复制文件等,代码如下:

/*** Author : BlackHao* Time : 2018/5/10 14:53* Description : USB 操作工具类* Logs :*/public class UsbHelper {//上下文对象private Context context;//USB 设备列表private UsbMassStorageDevice[] storageDevices;//USB 广播private USBBroadCastReceiver mUsbReceiver;//回调private USBBroadCastReceiver.UsbListener usbListener;//当前路径private UsbFile currentFolder = null;//TAGprivate static String TAG = "UsbHelper";public UsbHelper(Context context, USBBroadCastReceiver.UsbListener usbListener) {this.context = context;this.usbListener = usbListener;//注册广播registerReceiver();}/*** 注册 USB 监听广播*/private void registerReceiver() {mUsbReceiver = new USBBroadCastReceiver();mUsbReceiver.setUsbListener(usbListener);//监听otg插入 拔出IntentFilter usbDeviceStateFilter = new IntentFilter();usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);context.registerReceiver(mUsbReceiver, usbDeviceStateFilter);//注册监听自定义广播IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);context.registerReceiver(mUsbReceiver, filter);}/*** 读取 USB设备列表** @return USB设备列表*/public UsbMassStorageDevice[] getDeviceList() {UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);//获取存储设备storageDevices = UsbMassStorageDevice.getMassStorageDevices(context);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);//可能有几个 一般只有一个 因为大部分手机只有1个otg插口for (UsbMassStorageDevice device : storageDevices) {//            Log.e(TAG, device.getUsbDevice().getDeviceName());//有就直接读取设备是否有权限if (!usbManager.hasPermission(device.getUsbDevice())) {//没有权限请求权限usbManager.requestPermission(device.getUsbDevice(), pendingIntent);}}return storageDevices;}/*** 获取device 根目录文件** @param device USB 存储设备* @return 设备根目录下文件列表*/public ArrayList<UsbFile> readDevice(UsbMassStorageDevice device) {ArrayList<UsbFile> usbFiles = new ArrayList<>();try {//初始化device.init();//获取partitionPartition partition = device.getPartitions().get(0);FileSystem currentFs = partition.getFileSystem();//获取根目录UsbFile root = currentFs.getRootDirectory();currentFolder = root;//将文件列表添加到ArrayList中Collections.addAll(usbFiles, root.listFiles());} catch (Exception e) {e.printStackTrace();}return usbFiles;}/*** 读取 USB 内文件夹下文件列表** @param usbFolder usb文件夹* @return 文件列表*/public ArrayList<UsbFile> getUsbFolderFileList(UsbFile usbFolder) {//更换当前目录currentFolder = usbFolder;ArrayList<UsbFile> usbFiles = new ArrayList<>();try {Collections.addAll(usbFiles, usbFolder.listFiles());} catch (IOException e) {e.printStackTrace();}return usbFiles;}/*** 复制文件到 USB** @param targetFile       需要复制的文件* @param saveFolder       复制的目标文件夹* @param progressListener 下载进度回调* @return 复制结果*/public boolean saveSDFileToUsb(File targetFile, UsbFile saveFolder, DownloadProgressListener progressListener) {boolean result;try {//USB文件是否存在boolean isExist = false;UsbFile saveFile = null;for (UsbFile usbFile : saveFolder.listFiles()) {if (usbFile.getName().equals(targetFile.getName())) {isExist = true;saveFile = usbFile;}}if (isExist) {//文件已存在,删除文件saveFile.delete();}//创建新文件saveFile = saveFolder.createFile(targetFile.getName());//开始写入FileInputStream fis = new FileInputStream(targetFile);//读取选择的文件的int avi = fis.available();UsbFileOutputStream uos = new UsbFileOutputStream(saveFile);int bytesRead;byte[] buffer = new byte[1024 * 8];int writeCount = 0;while ((bytesRead = fis.read(buffer)) != -1) {uos.write(buffer, 0, bytesRead);writeCount += bytesRead;
//                Log.e(TAG, "Progress : " + (writeCount * 100 / avi));if (progressListener != null) {//回调下载进度progressListener.downloadProgress(writeCount * 100 / avi);}}uos.flush();fis.close();uos.close();result = true;} catch (final Exception e) {e.printStackTrace();result = false;}return result;}/*** 复制 USB文件到本地** @param targetFile       需要复制的文件* @param savePath         复制的目标文件路径* @param progressListener 下载进度回调* @return 复制结果*/public boolean saveUSbFileToLocal(UsbFile targetFile, String savePath,DownloadProgressListener progressListener) {boolean result;try {//开始写入UsbFileInputStream uis = new UsbFileInputStream(targetFile);//读取选择的文件的FileOutputStream fos = new FileOutputStream(savePath);//这里uis.available一直为0
//            int avi = uis.available();long avi = targetFile.getLength();int writeCount = 0;int bytesRead;byte[] buffer = new byte[1024];while ((bytesRead = uis.read(buffer)) != -1) {fos.write(buffer, 0, bytesRead);writeCount += bytesRead;
//                Log.e(TAG, "Progress : write : " + writeCount + " All : " + avi);if (progressListener != null) {//回调下载进度progressListener.downloadProgress((int) (writeCount * 100 / avi));}}fos.flush();uis.close();fos.close();result = true;} catch (Exception e) {e.printStackTrace();result = false;}return result;}/*** 获取上层目录文件夹** @return usbFile : 父目录文件 / null :无父目录*/public UsbFile getParentFolder() {if (currentFolder != null && !currentFolder.isRoot()) {return currentFolder.getParent();} else {return null;}}/*** 获取当前 USBFolder*/public UsbFile getCurrentFolder() {return currentFolder;}/*** 退出 UsbHelper*/public void finishUsbHelper() {context.unregisterReceiver(mUsbReceiver);}/*** 下载进度回调*/public interface DownloadProgressListener {void downloadProgress(int progress);}
}

DEMO

截图

写了个demo,主要就是Android本地网文件和USB文件相互复制,截图如下:

拷贝文件到U盘

拷贝文件到本地

DEMO源码下载地址

CSDN下载:https://download.csdn.net/download/a512337862/10459222
Github:https://github.com/LuoChen-Hao/BlackHaoUtil

结语

  • 因为本人文字功底有限,所以介绍性的文字很少,但是基本上每句代码都加了注释,理解起来应该不难,如果有任何问题,可以留言。
  • Demo相关的代码代码未贴出,可以自行下载源码参考。

Android 基于libaums实现读写U盘文件相关推荐

  1. GD32F427使用HAL库读写U盘文件的BUG

    GD32F427使用HAL库读写U盘文件时(使用Fatfs文件系统),上电后,第一次读U盘文件,当文件大于11KB后,总是卡死,卡在USB状态这边,一直报BUSY.导致USB底层报超时故障.解决方法: ...

  2. 劢领AT|五分钟,使用AT指令读写U盘文件

    劢领AT|五分钟,使用AT指令读写U盘文件 实验前准备 WIFI模块AT指令操作U盘文件 例程1:创建文件并写入数据 例程2:读取文件中的数据 连续读写功能使用 其它AT指令 实验前准备 本手册适用于 ...

  3. Android基于nfc的读写(一)

    这里写自定义目录标题 Android的NFC读写(一) NFC简介 代码解析 源码(Demo) Android的NFC读写(一) 近来,因需求需要开发nfc读写功能,网上查阅了许多资料,发现相关方面资 ...

  4. qt linux不能读写u盘文件,Qt读取U盘文件内容

    欢迎大家关注.收藏,方便下次阅读! 之前想做的一个功能是读取U盘中的文件到系统磁盘目录下,今天抽空把简版功能实现了.那会儿一直搜索的Qt如何识别U盘,最终得到的结果是Qt检测U盘插拔,发现并不是我想要 ...

  5. uboot中挂载U盘,利用FAT文件系统读写U盘文件

    关于使用U盘自动更新系统镜像,请看我的这篇博文:http://blog.chinaunix.net/space.php?uid=22030783&do=blog&id=3347599 ...

  6. Android-USB-OTG-读写U盘文件

    参考: https://developer.android.com/guide/topics/connectivity/usb/host.html https://blog.csdn.net/qq_2 ...

  7. USB应用开发笔记之一:STM32上实现USB主机读写U盘

      在项目应用中,经常会有对外交换数据的需求.USB接口读写U盘无疑是一种颇为方便的选择.在这一篇中,我们就来讨论如何在STM32上实现USB主机读写U盘文件的方法. 1.应用概述   在我们的产品上 ...

  8. Android U盘文件读写复制操作

    Android U盘文件读写复制操作 应用开发起因 一.U盘的拔插监听及读取U盘设备 二.读取文件列表 1.U盘文件列表读取 2.Storage文件列表读取 三.通过文件列表进入文件,进行文本文件的读 ...

  9. android免root读写u盘最新方法,支持安卓Q+

    android读写u盘支持安卓10以上的最新方法 本人是在写一个app需要读取u盘文件列表,网上找了好多方法,要不就是没有media权限,要不就是收不到广播,全部用不了,就这样搁置了一段时间终于又找到 ...

最新文章

  1. [R语言画图]气泡图symbols
  2. MySQL使用裸设备
  3. 学习笔记11-C语言-指针
  4. 对接闪送_中国快递业加速出海,圆通上线“全球闪送”,与顺丰、申通抢市场...
  5. 小程序 onReachBottom 事件快速滑动时不触发的bug
  6. 印象笔记如何与微信连接到服务器,如何保存微信和微博到印象笔记?
  7. 数据库mongodb效率测试
  8. 开发独立证券交易系统的一些体会,有下单撮合系统,自己产生交易行情,可实现分布式部署
  9. mysql 8.0开启远程访问
  10. codewars练习(javascript)-2021/2/10
  11. php表格单元格怎么实现排序,excel表格数据怎么自动排列-excel表格如何实现自动排序...
  12. 收藏!数学节为你推荐10本数学好书!
  13. huffman编码译码器用c语言,基于哈弗曼编码的数据压缩C语言实现
  14. json tobean
  15. 高版本的SQLServer2016 还原到低版本的SQL Server2012
  16. DSP ADAU1452输入与ASRC之间的关系
  17. phpstudy和thinkPHP的安装
  18. 学习四旋翼(一):动力学模型和空间姿态表示
  19. 编程规范及程序员的自我修养
  20. 鸿蒙珠融入体内,斗罗大陆同人小说排行榜。第一名:《斗罗大陆之超级无敌》:主角...

热门文章

  1. 高德地图——骑行导航
  2. ENSP 防火墙USG6000V NAT 设置(全场景)
  3. JAVA、IDEA超级实用快捷键(公司开发项目中常用快捷键)
  4. 创建和使用静态链接库
  5. B树(BTree)与B+树(B+Tree)
  6. js前端base64转码解码
  7. React 之使用echar注意事项
  8. 图像锐化(增强)和边缘检测
  9. SpringBoot 腾讯企业邮箱
  10. 机器学习隐私保护-MPC通用编译器