Android U盘文件读写复制操作

应用开发起因

起因是公司导师让我研究一下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的文件写入读取,接触到了图片的读取写入。
可以说这次的应用开发给我自己带来的提升是全方位的,不仅是在写代码上,更多的是自学研究能力的提升。
这个应用可能还不是很成熟,存在有很多问题,希望有看到的人可以与我交流探讨,我很乐意与需要的人一起分享问题的解决。

  • 8
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: Android U盘读写是指在Android系统设备上使用U盘进行数据传输和存储的过程。在Android系统中,U盘通常使用USB接口与设备连接,通过USB On-The-Go(简称USB OTG)技术可以使设备拥有读写U盘的能力。 要在Android设备上读写U盘,首先需要确保设备支持USB OTG功能,并且安装了相应的驱动程序。然后将U盘插入设备的USB接口,系统会自动识别U盘,并在文件管理器中显示其中的文件和文件夹列表。接着就可以像在电脑上操作一样进行文件的拷贝、移动、删除等操作了。 需要注意的是,不同设备对U盘读写的支持程度可能有所不同。有些设备可能只能读取U盘中的文件,而不能写入,或者只能写入部分格式的文件。此外,U盘的格式也会影响设备的读写能力。因此,在使用之前需要先了解设备和U盘的限制,以避免数据丢失或损坏。 总的来说,Android U盘读写功能的便利性和灵活性使其成为很多人进行数据传输和备份的首选方式。对于需要频繁进行数据交换的用户来说,它的作用是不可替代的。 ### 回答2: 对于android u盘读写,首先需要保证你的android设备支持OTG(On-The-Go)功能。 如果你的设备支持OTG,可以通过OTG线连接U盘android设备,然后直接在安卓设备上找到文件管理器,就能看到u盘的存储设备了。 接下来,你可以打开文件管理器,浏览U盘中的文件,并进行读写操作。如果需要复制文件到U盘,则直接在文件管理器中选择要复制的文件,然后将其粘贴到U盘的根目录或指定文件夹下即可。同样,如果需要从U盘复制文件到android设备,则选择要复制的文件,将其粘贴到想要存储的android设备文件夹下即可。 需要注意的是,在android设备上对于U盘进行读写操作时,需要牢记安全移除U盘的步骤,否则会将数据损坏。 总的来说,使用OTG线连接U盘android设备,通过文件管理器进行读写操作是十分方便的,因此在出门旅行时,将重要文件存储在U盘中,即可随时实现安卓设备和电脑之间的数据互传。 ### 回答3: Android设备上的U盘读写操作并不像在电脑上那么简单,需要一些必要的前置条件。首先,您需要连接一根OTG(On-The-Go)线缆将U盘Android设备连接起来。OTG线缆的一端是一个Micro USB端口,另一端是一个USB2.0或3.0端口,您应该根据自己的设备来选择合适的线缆类型。 接下来,当您连接U盘后,您的Android设备或许会出现一个提示框,问您想如何处理连接的U盘,这将由您自己决定。然后,您需要查看U盘是否已经正确识别,可以在“文件管理器”应用程序中看到U盘是否出现在文件列表中。如果您不能看到它,请尝试断开连接并重新连接U盘,或者重启您的Android设备并再次连接U盘。 此时您可以打开U盘并开始读写操作了。要复制文件到U盘,请单击并长按要复制的文件,选择“复制”,然后进入U盘,再次单击并长按空白区域,选择“粘贴”完成文件复制。同样,您也可以使用相同的方法将U盘上的文件复制Android设备上,只需要选择粘贴的目标是您的设备内存或SD卡即可。 但是,需要注意的是,在进行读写U盘操作时,请勿在拔出U盘之前来回插拔U盘,否则可能会导致文件损坏。在不需要使用时,应该先卸载U盘,然后再从Android设备上断开连接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值