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

工作中使用libaums来操作U盘,即OTG功能。转载一篇文章,写得很好。

转载自:https://blog.csdn.net/a512337862/article/details/80505128

本文主要介绍利用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";

    @Override
    public 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;
    //TAG
    private 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();
            //获取partition
            Partition 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相关的代码代码未贴出,可以自行下载源码参考

猜你喜欢

转载自blog.csdn.net/u010144805/article/details/81130692