Android U盘 读写

首先给予足够的读写权限:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<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" />

其次添加一个U盘读写操作的依赖包,我用的也是大家都推荐的:

compile 'com.github.mjdev:libaums:0.5.5'

继续上代码:首先是写操作(注意:需要你的手机root了才可以)

第一步:注册广播

/**
 * @description OTG广播注册
 * @author ldm
 * @time 2017/9/1 17:19
 */
private void registerUDiskReceiver() {
    //监听otg插入 拔出
    IntentFilter usbDeviceStateFilter = new IntentFilter();
    usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    registerReceiver(mOtgReceiver, usbDeviceStateFilter);
    //注册监听自定义广播
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(mOtgReceiver, filter);
}
/**
 * @description OTG广播,监听U盘的插入及拔出
 * @author ldm
 * @time 2017/9/1 17:20
 * @param
 */
private BroadcastReceiver mOtgReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        switch (action) {
            case ACTION_USB_PERMISSION://接受到自定义广播
                usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                //允许权限申请
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (usbDevice != null) {
                        //用户已授权,可以进行读取操作
                        readDevice(getUsbMass(usbDevice));
                    } else {
                        showToastMsg("没有插入U");
                    }
                } else {
                    showToastMsg("未获取到U盘权限");
                }
                break;
            case UsbManager.ACTION_USB_DEVICE_ATTACHED://接收到U盘设备插入广播
                UsbDevice device_add = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (device_add != null) {
                    //接收到U盘插入广播,尝试读取U盘设备数据
                    redUDiskDevsList();
                }
                break;
            case UsbManager.ACTION_USB_DEVICE_DETACHED://接收到U盘设设备拔出广播
                showToastMsg("U盘已拔出");
                break;
        }
    }
};

设备读取

/**
 * @description U盘设备读取
 * @author ldm
 * @time 2017/9/1 17:20
 */
private void redUDiskDevsList() {
    //设备管理器
    UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    //获取U盘存储设备
    storageDevices = UsbMassStorageDevice.getMassStorageDevices(this);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    //一般手机只有1OTG插口
    for (UsbMassStorageDevice device : storageDevices) {
        //读取设备是否有权限
        if (usbManager.hasPermission(device.getUsbDevice())) {
            readDevice(device);
        } else {
            //没有权限,进行申请
            usbManager.requestPermission(device.getUsbDevice(), pendingIntent);
        }
    }
    if (storageDevices.length == 0) {
        showToastMsg("请插入可用的U");
    }
}

设备写入:

/**
 * @description 保存数据到U盘,目前是保存到根目录的
 * @author ldm
 * @time 2017/9/1 17:17
 */
private void saveText2UDisk(String content) {
    //项目中也把文件保存在了SD卡,其实可以直接把文本读取到U盘指定文件
    File file = FileUtil.getSaveFile(getPackageName()
                    + File.separator + FileUtil.DEFAULT_BIN_DIR,
            U_DISK_FILE_NAME);
    try {
        FileWriter fw = new FileWriter(file);
        fw.write(content);
        fw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if (null != cFolder) {
        FileUtil.saveSDFile2OTG(MainActivity.this,file, cFolder);
        mHandler.sendEmptyMessage(100);
    }
}

文件操作类:

public class FileUtil {
    public static final String DEFAULT_BIN_DIR = "usb";

    /**
     * 检测SD卡是否存在
     */
    public static boolean checkSDcard() {
        return Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState());
    }

    /**
     * 从指定文件夹获取文件
     *
     * @return 如果文件不存在则创建, 如果如果无法创建文件或文件名为空则返回null
     */
    public static File getSaveFile(String folderPath, String fileNmae) {
        File file = new File(getSavePath(folderPath) + File.separator
                + fileNmae);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 获取SD卡下指定文件夹的绝对路径
     *
     * @return 返回SD卡下的指定文件夹的绝对路径
     */
    public static String getSavePath(String folderName) {
        return getSaveFolder(folderName).getAbsolutePath();
    }

    /**
     * 获取文件夹对象
     *
     * @return 返回SD卡下的指定文件夹对象,若文件夹不存在则创建
     */
    public static File getSaveFolder(String folderName) {
        File file = new File(getExternalStorageDirectory()
                .getAbsoluteFile()
                + File.separator
                + folderName
                + File.separator);
        file.mkdirs();
        return file;
    }

    /**
     * 关闭流
     */
    public static void closeIO(Closeable... closeables) {
        if (null == closeables || closeables.length <= 0) {
            return;
        }
        for (Closeable cb : closeables) {
            try {
                if (null == cb) {
                    continue;
                }
                cb.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void redFileStream(OutputStream os, InputStream is) throws IOException {
        int bytesRead = 0;
        byte[] buffer = new byte[1024 * 8];
        while ((bytesRead = is.read(buffer)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.flush();
        os.close();
        is.close();
    }

    public static List<String> getAllExterSdcardPath()
    {
        List<String> SdList = new ArrayList<String>();

        String firstPath = Environment.getExternalStorageDirectory().getPath();

        try
        {
            Runtime runtime = Runtime.getRuntime();
            // 运行mount命令,获取命令的输出,得到系统中挂载的所有目录
            Process proc = runtime.exec("mount");
            InputStream is = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            String line;
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null)
            {
                Log.d("", line);
                // 将常见的linux分区过滤掉

                if (line.contains("proc") || line.contains("tmpfs") || line.contains("media") || line.contains("asec") || line.contains("secure") || line.contains("system") || line.contains("cache")
                        || line.contains("sys") || line.contains("data") || line.contains("shell") || line.contains("root") || line.contains("acct") || line.contains("misc") || line.contains("obb"))
                {
                    continue;
                }

                // 下面这些分区是我们需要的
                if (line.contains("fat") || line.contains("fuse") || (line.contains("ntfs")))
                {
                    // mount命令获取的列表分割,items[0]为设备名,items[1]为挂载路径
                    String items[] = line.split(" ");
                    if (items != null && items.length > 1)
                    {
                        String path = items[1].toLowerCase(Locale.getDefault());
                        // 添加一些判断,确保是sd卡,如果是otg等挂载方式,可以具体分析并添加判断条件
                        if (path != null && !SdList.contains(path) && path.contains("sd"))
                            SdList.add(items[1]);
                    }
                }
            }
        } catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (!SdList.contains(firstPath))
        {
            SdList.add(firstPath);
        }

        return SdList;
    }


    /**
     * @description 把本地文件写入到U盘中
     * @author ldm
     * @time 2017/8/22 10:22
     */
    public static void saveSDFile2OTG(Context context,final File f, final UsbFile usbFile) {
        UsbFile uFile = null;
        FileInputStream fis = null;
        try {//开始写入
            fis = new FileInputStream(f);//读取选择的文件的
            if (usbFile.isDirectory()) {//如果选择是个文件夹
                UsbFile[] usbFiles = usbFile.listFiles();
                if (usbFiles != null && usbFiles.length > 0) {
                    for (UsbFile file : usbFiles) {
                        if (file.getName().equals(f.getName())) {
                            file.delete();
                        }
                    }
                }
                uFile = usbFile.createFile(f.getName());
                UsbFileOutputStream uos = new UsbFileOutputStream(uFile);
                try {
                    redFileStream(uos, fis);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (final Exception e) {
            e.printStackTrace();
            Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
        }
    }
}
private final static String U_DISK_FILE_NAME = "****.txt";//星号写自己要写入文件的文件名

读取操作:Ps:一开始以为挺简单,后面发现没那么简单

获取UsbDevice

private UsbMassStorageDevice getUsbMass(UsbDevice usbDevice) {
    if(usbDevice!=null){
        for (UsbMassStorageDevice device : storageDevices) {
            if (usbDevice.equals(device.getUsbDevice())) {
                return device;
            }
        }
    }
    return null;
}

初始化调用:

private void readDevice(UsbMassStorageDevice device) {
        try {
            device.init();//初始化
            //设备分区
            Partition partition = device.getPartitions().get(0);
            //文件系统
            currentFs = partition.getFileSystem();
            currentFs.getVolumeLabel();//可以获取到设备的标识
            //通过FileSystem可以获取当前U盘的一些存储信息,包括剩余空间大小,容量等等
            Log.e("Capacity: ", currentFs.getCapacity() + "");
            Log.e("Occupied Space: ", currentFs.getOccupiedSpace() + "");
            Log.e("Free Space: ", currentFs.getFreeSpace() + "");
            Log.e("Chunk size: ", currentFs.getChunkSize() + "");
            cFolder = currentFs.getRootDirectory();//设置当前文件对象为根目录
            UsbFile[] usbFiles=cFolder.listFiles();
            if (null != usbFiles && usbFiles.length > 0) {
                for (UsbFile usbFile : usbFiles) {
                    if (usbFile.getName().equals(U_DISK_FILE_NAME)) {
                        readFile(usbFile);
//                        readTxtFromUDisk(usbFile);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            android.widget.Toast.makeText(AddPwsAddressActivity.this,e.toString(), android.widget.Toast.LENGTH_LONG).show();
        }
    }
private void readFile(final UsbFile uFile) {
    String sdPath = SDUtils.getSDPath();//获取sd根目录 创建一个同名文件
    String filePath = sdPath + "/" + uFile.getName();
    final File f = new File(filePath);
    if (!f.exists()) {
        try {
            f.createNewFile();
            //设置视图
            //执行线程
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        FileOutputStream os = new FileOutputStream(f);
                        InputStream is = new UsbFileInputStream(uFile);
                        final String bt = redFileStream(os, is);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                android.widget.Toast.makeText(AddPwsAddressActivity.this,bt, android.widget.Toast.LENGTH_LONG).show();
                                Message msg = mHandler.obtainMessage();
                                msg.what = 101;
                                android.widget.Toast.makeText(AddPwsAddressActivity.this,bt, android.widget.Toast.LENGTH_LONG).show();
                                msg.obj = bt;
                                mHandler.sendMessage(msg);
                            }
                        });
                    } catch (final Exception e) {
                        e.printStackTrace();

                    }
                }
            });
        } catch (final Exception e) {
            e.printStackTrace();


        }
    }else {
        try {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        FileOutputStream os = new FileOutputStream(f);
                        InputStream is = new UsbFileInputStream(uFile);
                        final String bt = redFileStream(os, is);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                android.widget.Toast.makeText(AddPwsAddressActivity.this,bt, android.widget.Toast.LENGTH_LONG).show();
                                Message msg = mHandler.obtainMessage();
                                msg.what = 101;
                                android.widget.Toast.makeText(AddPwsAddressActivity.this,bt, android.widget.Toast.LENGTH_LONG).show();
                                msg.obj = bt;
                                mHandler.sendMessage(msg);
                            }
                        });
                    } catch (final Exception e) {
                        e.printStackTrace();

                    }
                }
            });
        } catch (final Exception e) {
            e.printStackTrace();


        }
    }
}

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case 100:
                showToastMsg("保存成功");
                break;
            case 101:
                if(msg.obj==null){
                    Toast.makeText(MainActivity.this,"空的",Toast.LENGTH_LONG).show();
                }else{
                    String txt = msg.obj.toString();
                    if (!TextUtils.isEmpty(txt))
                        u_disk_show.setText("读取到的数据是:" + txt);
                }
                break;
        }
    }
};

Ps:别忘记反注册广播

特别感谢(对代码有疑问的可以提给我或者去看这两篇博客):

https://blog.csdn.net/csdn635406113/article/details/70146041

https://blog.csdn.net/true100/article/details/77775700

还要感谢我朋友猴子的无私分享~

sd卡工具类:

public class SDUtils {
    private static final String TAG = "文件工具类";

    public static String getSDPath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(Environment.MEDIA_MOUNTED); //判断sd卡是否存在
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();//获取跟目录
//            sdDir1 = Environment.getDataDirectory();
//            sdDir2 = Environment.getRootDirectory();
        } else {
            Log.d(TAG, "getSDPath: sd卡不存在");
        }
        Log.d(TAG, "getSDPath: " + sdDir.getAbsolutePath());
        return sdDir.getAbsolutePath();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值