Android U盘文件读写复制操作 应用开发起因 总结 最后

前言

今天群友在说公司要求他开发一个Android的U盘读写APP(具体要求就不说了),然后就有群友分享了这篇文,大家都说这个文写的不错,受益匪浅。所以,在这里就分享给大家,希望对大家的工作和学习有所帮助。

另外,我们群是一个非常活跃的两千人技术交流圈,对Android感兴趣的朋友欢迎加入我们,私信我获得群密码(群专属海量学习资源,免费共享)。

应用开发起因

起因是公司导师让我研究一下Android如何通过apk来访问u盘,往u盘里面写数据。需求下来了,就开始研究了,之前完全没有接触过Android与usb之间的内容,那就少不了了各种查资料了。

在网上翻了半天,不过网上这块的资料也是非常的少,这也更加坚定了我要写一个这样的应用出来。网上大概都是这样的,实现读取u盘里的txt文件,往u盘的txt文件里写入数据,可能确实是这块比较冷门,都没有一个完整一点的应用。

我思考了很久,大概有了一个应用的雏形,有两个文件列表,一个是Android系统的文件列表,一个是U盘的文件列表,可以实现两边文本的读写数据,实现两边之间文本的复制,还有一个功能是后来导师提出的,实现图片的读写。

那么,计划了这么多,就开干吧!

一.U盘的拔插监听及读取U盘设备

这个应该是此应用开发的第一步,我先研究的是U盘的拔插监听,这里要用到两个监听标志。

ACTION_USB_DEVICE_ATTACHED
ACTION_USB_DEVICE_DETACHED

一个代表u盘插入,一个代表u盘拔出,再来看看usbManager里的这俩。

"android.hardware.usb.action.USB_DEVICE_ATTACHED"
"android.hardware.usb.action.USB_DEVICE_DETACHED"

有了这两个标志就简单了许多了

        //监听otg插入 拔出
        IntentFilter usbDeviceStateFilter = new IntentFilter();
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        registerReceiver(mOtgReceiver, usbDeviceStateFilter);

通过注册这两个标志的监听,来实现u盘拔插的广播

               case UsbManager.ACTION_USB_DEVICE_ATTACHED://接收到U盘设备插入广播
                    showToastMsg("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盘已拔出");
                    redUDiskDevsList();
                    break;

使用showToastMsg()方法来广播u盘的拔插情况,当插入时再去调用redUDiskDevsList()方法,读取u盘数据。

private boolean 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);
        //一般手机只有1个OTG插口
        for (UsbMassStorageDevice device : storageDevices) {
            //读取设备是否有权限
            if (usbManager.hasPermission(device.getUsbDevice())) {
                readDevice(device);
                mU_disk_ok = true;
                Log.d(TAG, "获取到权限: "+mU_disk_ok);
            } else {
                //没有权限,进行申请
                usbManager.requestPermission(device.getUsbDevice(), pendingIntent);
            }
        }
        if (storageDevices.length == 0) {
            u_disk_message.setText("请插入可用的U盘");
            mU_disk_ok = false;
        }else {
            u_disk_message.setText("");
        }
        return mU_disk_ok;
    }

这个讲一个mU_disk_ok这个标志,是我用来解决在进行操作时u盘是否实时保证插入并且获取到了权限,因为在开发过程中遇到一个问题。

当先插入了u盘获取了权限以后,把u盘拔出,再去做U盘的一些操作,这就会导致一些bug的产生,所以对u盘的权限判断应该是实时的,每次执行操作都要去判断一次。使用mU_disk_ok作为redUDiskDevsList()方法的返回值,当redUDiskDevsList()为true时才执行u盘操作,否则提示请插入u盘。

再来看看readDevice(device)这个方法,在讲这个之前有一个东西不能不提,libaums。这个是我在查阅资料时,基本网上涉及到usb操作的开发都会用到libaums这么一个开源框架。

那么就简单的介绍一下libaums框架,来自于github上的介绍,A library to access USB mass storage devices (pen drives, external HDDs, card readers) using the Android USB Host API. Currently it supports the SCSI command set and the FAT32 file system.大致就是说这是一个一个使用Android USB Host API访问USB存储设备的库,目前支持SCSI命令集和FAT32文件系统。

其实你只要知道,使用他可以帮助你开发usb的一些操作。

来看看如何使用,The library can be included into your project like this:

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

只要引用一下libaums,就可以了。
再说回到readDevice(device),这个方法在libaums有使用的示例介绍

UsbMassStorageDevice[] devices = UsbMassStorageDevice.getMassStorageDevices(this /* Context or Activity */);

for(UsbMassStorageDevice device: devices) {

    // before interacting with a device you need to call init()!
    device.init();

    // Only uses the first partition on the device
    FileSystem currentFs = device.getPartitions().get(0).getFileSystem();
    Log.d(TAG, "Capacity: " + currentFs.getCapacity());
    Log.d(TAG, "Occupied Space: " + currentFs.getOccupiedSpace());
    Log.d(TAG, "Free Space: " + currentFs.getFreeSpace());
    Log.d(TAG, "Chunk size: " + currentFs.getChunkSize());
}

那么到这里,通过使用libaums的开源库,帮助我们实现了第一步的开发,U盘的拔插监听及读取U盘设备。

二.读取文件列表

第二步,读取文件列表,我的想法是把Android系统内部存储和u盘的文件列表都直观的读取出来。

1.U盘文件列表读取

如何把U盘的文件列表读取出来,很重要的一点,通过cFolder拿到u盘根目录的路径。

cFolder = currentFs.getRootDirectory();

拿到根目录以后就好办了,只要去遍历出根目录下的文件名,添加到list中,再放到ArrayAdapter,通过listView进行显示即可。

            List list = new ArrayList<>();
            UsbFile[] usbFiles = new UsbFile[0];
            try {
                usbFiles = cFolder.listFiles();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (null != usbFiles && usbFiles.length > 0) {
                for (UsbFile usbFile : usbFiles) {
                    Log.d(TAG, "usbFile: "+usbFile.getName());
                    list.add(usbFile.getName());
                }
            }
            final String[] data = new String[list.size()];
            for(int i=0;i<list.size();i++){
                data[i] = String.valueOf(list.get(i));
            }
            ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
                    MainActivity.this,android.R.layout.simple_list_item_1,data);
            u_disk_list.setAdapter(arrayAdapter);

2.Storage文件列表读取

实现了u盘的文件列表读取,再来研究下Android系统内部存储的文件列表读取。同样的,第一步就是要拿到内部存储根目录的路径。

而在读取storage的文件列表前也是跟u盘操作一样要先获取到storage存储权限。这里又到了一个重点了,在Android sdk23之前,只要再AndroidManifest.xml中有这么两句就可以了。

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

而到了23以后,必须再手动去获取一下权限

        int permission = ActivityCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE);
        }

除此之外,这里再稍微讲解一下Android系统的内部存储与外部存储,在以前的Android系统下,即4.4版本以前,就像我们的电脑一样理解,电脑的硬盘算是内部存储,而插入的移动硬盘算是外部存储,而对于Android系统来说,系统的内部空间算内部存储,插入的sd卡算外部存储。

而在Android4.4以后,由于科技的发展,各种的Android机子都扩展了自己的机身存储,比如8G,16G,到现在的64G 128G及以上。

这个在物理上也算是机身本身的内部存储,因为它是直接集成在Android机子里的,但是在概念的叫法上变成了“外部存储”,与sd卡一样,原来Android系统内部的空间还是称为内部存储。

不懂我解释的大家能不能理解,总得来说就是4.4以后,Android的存储分为“内部存储”与“外部存储”,机身自带的32G 64G的存储在物理上确实是“内部”,但是它仍被称为“外部存储”,与sd卡一样。也就是说在4.4以后,即使你不插sd卡(现在也很少用sd卡了),它也是存在外部存储的。

private final String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath().toString();

这样拿到的路径应该是,/storage/emulated/0 这么个路径。

拿到存储路径就完了吗?到这里我运行发现一直报permission deny的错误,明明我有手动获取了权限的啊,甚至我还打开的设置》应用》权限,在里面确保了storage的权限开启,为什么还是会报这样的错误呢?
原来是因为我使用的是Android10.0的系统,10.0有一个新特性。

在Android Q中引入了分区储存功能,在外部存储设备中为每个应用提供了一个“隔离存储沙盒”。其他应用无法直接访问应用的沙盒文件。由于文件是应用的私有文件,不再需要任何权限即可访问和保存自己的文件。此变更并有助于减少应用所需的权限数量,同时保证用户文件的隐私性。Android Q 更改了应用对设备外部存储设备中的文件(如:/sdcard )的访问方式。

继续使用 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限,只不过当拥有这些权限的时候,你只能访问媒体文件,无法访问其他文件。

有这么一个方法可以选择停用分区存储,在AndroidManifest中添加android:requestLegacyExternalStorage=“true”。
果然,问题解决了!

            List list = new ArrayList<>();
            File storagefile = new File(storagePath);
            File[] files = storagefile.listFiles();
            if (null != files && files.length > 0) {
                for (File file : files) {
                    Log.d(TAG, "File: "+file.getName());
                    list.add(file.getName());
                }
            }
            final String[] data = new String[list.size()];
            for(int i=0;i<list.size();i++){
                data[i] = String.valueOf(list.get(i));
            }
            ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
                    MainActivity.this,android.R.layout.simple_list_item_1,data);
            storage_list.setAdapter(arrayAdapter);

同样的,通过ListView把文件列表给显示出来。

三.通过文件列表进入文件,进行文本文件的读取及写入数据操作

这里有分成两个模块,一个是u盘文本文件的读写数据操作,一个是Storage文本文件的读写数据操作。

1.U盘文本文件的读写操作

(1)U盘文本文件的数据读取

首先,来说说u盘的,通过点击ListView,进入新的activity并把所选的文件名传过去。

u_disk_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if(data[position].endsWith(".txt")) {
                        Intent intent = new Intent(MainActivity.this, UDiskReadAndWriteTxt.class);
                        intent.putExtra("filename", data[position]);
                        startActivity(intent);
                    }         
            });

再到新的activity拿到传过来的文件名

        Intent intent = getIntent();
        mU_DISK_FILE_NAME = intent.getStringExtra("filename");

然后是两个操作,读取和写入,先讲读取。思路就是在u盘根目录的文件下遍历找到传过来的文件名的文本文件

            UsbFile[] usbFiles = new UsbFile[0];
            try {
                usbFiles = cFolder.listFiles();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (null != usbFiles && usbFiles.length > 0) {
                for (UsbFile usbFile : usbFiles) {
                    Log.d(TAG, "usbFile: "+usbFile.getAbsolutePath());
                    if (usbFile.getName().equals(mU_DISK_FILE_NAME)) {
                        readTxtFromUDisk(usbFile);
                    }
                }
            }

拿到usbFile以后,通过文件流InputStream来进行读取。

        UsbFile descFile = usbFile;
        //读取文件内容
        InputStream is = new UsbFileInputStream(descFile);
        //读取秘钥中的数据进行匹配
        StringBuilder sb = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(is));
            String read;
            while ((read = bufferedReader.readLine()) != null) {
                sb.append(read);
            }
            Message msg = mHandler.obtainMessage();
            msg.what = 101;
            msg.obj = sb;
            mHandler.sendMessage(msg);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

我采用的方法是统一使用一个Handler来进行数据的接收。

            switch (msg.what) {
                case 101:
                    showToastMsg("读取成功");
                    String txt = msg.obj.toString();
                    if (!TextUtils.isEmpty(txt))
                        u_disk_edt.setText(txt);
                    break;
            }

(2)U盘文本文件的数据写入

先想想思路,跟读取数据一样,遍历u盘的根目录文件,找到传过来的文件名的文本文件,然后进行输入框传过来的数据写入。

            try {
                //获取根目录的文件
                UsbFile[] usbFiles = cFolder.listFiles();
                //如果有文件则遍历文件列表
                if (usbFiles != null && usbFiles.length > 0) {
                    for (UsbFile file : usbFiles) {
                        Log.d(TAG, "file: "+file.getName());
                        if (file.getName().equals(mU_DISK_FILE_NAME)) {
                            OutputStream os = new UsbFileOutputStream(file);
                            os.write(content.getBytes());
                            os.close();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            mHandler.sendEmptyMessage(100);

这块的代码,文件遍历上与读取时一样,匹配完文件名以后通过OuputStream文件流来写入数据。
写入成功后,提示信息,“保存成功”

            switch (msg.what) {
                case 100:
                    showToastMsg("保存成功");
                    break;
            }

2.Storage文本文件的读写操作

(1)Storage文本文件的数据读取

思路与u盘文本文件的读取基本一致,不同在于不用去遍历文件来获取usbFile文件,只需要拿到文件的路径,直接就可以拿到文件。
其中file就是Storage中文本文件的路径。

File txtFile = new File(file);
            //读取文件内容
            InputStream is = null;
            try {
                is = new FileInputStream(txtFile);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            //读取秘钥中的数据进行匹配
            StringBuilder sb = new StringBuilder();
            BufferedReader bufferedReader = null;
            try {
                bufferedReader = new BufferedReader(new InputStreamReader(is));
                String read;
                while ((read = bufferedReader.readLine()) != null) {
                    sb.append(read);
                }
                Message msg = mHandler.obtainMessage();
                msg.what = 101;
                msg.obj = sb;
                mHandler.sendMessage(msg);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

(2)Storage文本文件的数据写入

这一块没啥好讲的,就把Storage的读取与u盘的写入结合一下就出来了。

            FileOutputStream fos = null;
            File txtFile = new File(file);
            try {
                fos = new FileOutputStream(txtFile);
                fos.write(content.getBytes());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            mHandler.sendEmptyMessage(100);

四.通过文件列表进入文件,进行图片的读取操作

其实写完上面的功能,这个应用的基础功能就已经完成了,做到了对u盘拔插的监听,对u盘设备的读取,对u盘及Storage文件列表的读取,文本文件的读写。读取图片这个功能,是我在网上没有看到过的功能,而且之前也没有接触过图片的读取,更不用说对u盘里图片的读取了。
那么就开始研究吧,先看看图片应该怎么读取出来?
通过ImageView的setImageBitmap()方法就可以把图片读取出来,而传入的参数是Bitmap,那么就是要获取到图片的Bitmap。

1.u盘图片的读取

一开始的工作与之前一样,先遍历U盘文件拿到usbFile,使用关键点在于,使用BufferedInputStream采用缓存的方式来读取图片,再使用BitmapFactory.decodeStream来解码图片,拿到Bitmap。

        UsbFile imgFile = usbFile;
        Bitmap bitmap = null;
        try {
            BufferedInputStream bis = new BufferedInputStream(new UsbFileInputStream(usbFile));
            bitmap = BitmapFactory.decodeStream(bis);
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Message msg = mHandler.obtainMessage();
        msg.what = 102;
        msg.obj = bitmap;
        mHandler.sendMessage(msg);

拿到了Bitmap后,用ImageView的setImageBitmap()方法进行图片的显示。

            switch (msg.what) {
                case 102:
                    showToastMsg("读取成功");
                    Bitmap bitmap = (Bitmap) msg.obj;
                    u_disk_img_show.setImageBitmap(bitmap);
                    break;
            }

2.Storage图片的读取

搞定了u盘图片的读取,那Storage的读取就不在话下了。
可以直接上代码了。

        File imgFile = new File(file);
        Bitmap bitmap = null;
        try {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(imgFile));
            bitmap = BitmapFactory.decodeStream(bis);
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Bitmap bitmapImg = bitmap;

        Message msg = mHandler.obtainMessage();
        msg.what = 102;
        msg.obj = bitmapImg;
        mHandler.sendMessage(msg);

五.实现文本文件与图片在U盘与Storage之间的复制操作

1.实现文本文件在U盘与Storage之间的复制操作

(1)从U盘复制文本文件到Storage

复制操作与写入数据操作有写不同,写入是在已有的文本文件下进行数据的写入,而复制要做到的是先在U盘中读取出要复制的文本文件的内容,再在Storage创建文本文件,把读取到的内容写入。
不过在复制前还需要对Storage中的文件遍历进行判断,看是否已存在了要复制的文件。

            Boolean flag = false;
            File storagefile = new File(storagePath);
            File[] files = storagefile.listFiles();
            if (null != files && files.length > 0) {
                for (File file : files) {
                    if(file.getName().equals(fileName)){
                        showToastMsg("写入失败,文本已存在");
                        flag = true;
                    }
                }
            }

            if(flag == false){
                UsbFile[] usbFiles = new UsbFile[0];
                try {
                    usbFiles = cFolder.listFiles();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (null != usbFiles && usbFiles.length > 0) {
                    for (UsbFile usbFile : usbFiles) {
                        Log.d(TAG, "usbFile: "+usbFile.getAbsolutePath());
                        if (usbFile.getName().equals(fileName)) {
                            //读取文件内容
                            InputStream is = new UsbFileInputStream(usbFile);
                            //读取秘钥中的数据进行匹配
                            StringBuilder sb = new StringBuilder();
                            BufferedReader bufferedReader = null;
                            try {
                                bufferedReader = new BufferedReader(new InputStreamReader(is));
                                String read;
                                while ((read = bufferedReader.readLine()) != null) {
                                    sb.append(read);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                try {
                                    if (bufferedReader != null) {
                                        bufferedReader.close();
                                    }
                                    if(is != null){
                                        is.close();
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                            FileOutputStream fos = null;
                            File txtFile = new File(internalDir);
                            try {
                                fos = new FileOutputStream(txtFile);
                                fos.write(sb.toString().getBytes());
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }finally {
                                if (fos != null) {
                                    try {
                                        fos.close();
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            }

            mHandler.sendEmptyMessage(102);

(2)从Storage复制文本文件到U盘

有了上面的经验,这里的思路就是反向一下即可。
直接上代码了。

            Boolean flag = false;
            UsbFile usbFile = null;
            try {
                //获取根目录的文件
                UsbFile[] usbFiles = cFolder.listFiles();
                //如果有文件则遍历文件列表
                if (usbFiles != null && usbFiles.length > 0) {
                    for (UsbFile file : usbFiles) {
                        Log.d(TAG, "file: "+file.getName());
                        if (file.getName().equals(mU_DISK_FILE_NAME)) {
                            showToastMsg("写入失败,文本已存在");
                            flag = true;
                        }
                    }
                }
                //若所需文件未存在,创建所需文件
                if (flag == false){
                    FileInputStream fis = new FileInputStream(new File(txtFile));
                    StringBuilder sb = new StringBuilder();
                    BufferedReader bufferedReader = null;
                    try {
                        bufferedReader = new BufferedReader(new InputStreamReader(fis));
                        String read;
                        while ((read = bufferedReader.readLine()) != null) {
                            sb.append(read);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (bufferedReader != null) {
                                bufferedReader.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    usbFile = cFolder.createFile(uDiskFileName);
                    OutputStream os = new UsbFileOutputStream(usbFile);
                    os.write(sb.toString().getBytes());
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            mHandler.sendEmptyMessage(102);
        }else {
            storage_message.setText("必须插入可用U盘才可写入数据");
        }

2.实现图片文件在U盘与Storage之间的复制操作

(1)从U盘复制到Storage

思路上与文本文件是一样的,区别就在于文件的读取方式不同,图片采用的是BufferedInputStream和BufferedOutputStream的方式进行读取和写入。

            Boolean flag = false;
            UsbFile usbFile = null;
            try {
                File storagefile = new File(storagePath);
                File[] files = storagefile.listFiles();
                if (null != files && files.length > 0) {
                    for (File file : files) {
                        if(file.getName().equals(fileName)){
                            showToastMsg("图片已经存在");
                            flag = true;
                        }
                    }
                }
                //若所需文件未存在,创建所需文件
                if(flag == false){
                    //获取根目录的文件
                    UsbFile[] usbFiles = cFolder.listFiles();
                    //如果有文件则遍历文件列表
                    if (usbFiles != null && usbFiles.length > 0) {
                        for (UsbFile file : usbFiles) {
                            Log.d(TAG, "file: "+file.getName());
                            if (file.getName().equals(fileName)) {
                                BufferedInputStream bis = new BufferedInputStream(new UsbFileInputStream(file));
                                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(internalDir));
                                int n= 0;
                                while((n=bis.read())!=-1) { //将图片读出存入缓存区
                                    bos.write(n); //图片写入缓存区
                                }
                                bos.flush();//刷新缓冲区
                                bis.close();
                                bos.close();
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            Message msg = mHandler.obtainMessage();
            msg.what = 101;
            mHandler.sendMessage(msg);

(2)从Storage复制到U盘

没什么好说的,直接上代码。

            Boolean flag = false;
            UsbFile usbFile = null;
            try {
                //获取根目录的文件
                UsbFile[] usbFiles = cFolder.listFiles();
                //如果有文件则遍历文件列表
                if (usbFiles != null && usbFiles.length > 0) {
                    for (UsbFile file : usbFiles) {
                        Log.d(TAG, "file: "+file.getName());
                        if (file.getName().equals(fileName)) {
                            showToastMsg("图片已经存在");
                            flag = true;
                        }
                    }
                }
                //若所需文件未存在,创建所需文件
                if(flag == false){
                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(internalDir));
                    usbFile = cFolder.createFile(fileName);
                    BufferedOutputStream bos = new BufferedOutputStream(new UsbFileOutputStream(usbFile));
                    int n= 0;
                    while((n=bis.read())!=-1) { //将图片读出存入缓存区
                        bos.write(n); //图片写入缓存区
                    }
                    bos.flush();//刷新缓冲区
                    bis.close();
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            Message msg = mHandler.obtainMessage();
            msg.what = 101;
            mHandler.sendMessage(msg);

到此为止便实现了U盘与Storage之间文本文件及图片文件的复制操作了

总结

这次的u盘应用开发是我之前完全没有接触过的领域,可以说是从0开始研究,先了解Android与usb之间的api有哪些,通过查阅资料大概了解到需要什么样的功能,了解到超牛逼的libaums库,通过阅读libaums的英文介绍学会使用u盘文件系统;重新学习了一边Android的文件写入读取,接触到了图片的读取写入。

可以说这次的应用开发给我自己带来的提升是全方位的,不仅是在写代码上,更多的是自学研究能力的提升。

这个应用可能还不是很成熟,存在有很多问题,希望有看到的人可以与我交流探讨,我很乐意与需要的人一起分享问题的解决。

原文地址:https://blog.csdn.net/weixin_38737818/article/details/103893358

最后

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

常言:种一棵树最好的时间有两个,一个是十年前,另一个就是现在。

千里之行始于足下,愿你我共勉。

本文在开源项目:https://github.com/xieyuliang/Note-Android中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中...

这次就分享到这里吧,下篇见

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章