Android OTG U盘文件读写

最近要求对安卓平板开发时导出Excel表格到插在平板的U盘上,初步尝试发现,对U盘的文件读写只能操作Android/包名/的目录,不能直接写在根目录,不方便客户使用,于是研究了libaums的库可用是可用,但是调用其device.init() 方法后,就不能在文件管理里面看到U盘了,所以客户使用起来还是不方便,于是想到了Linux文件操作命令。

思路是先生成文件在内置存储卡中,然后使用Linux命令将文件cp或者mv到U盘根目录
复制命令
cp -r srcPath targetPath
剪切命令
mv srcPath targetPath

首先获取U盘的路径,代码如下,有返回值说明有U盘挂载,返回值为空说明U盘未挂载

    public static String getUDiskRealPath() {
        String filePath = "/proc/mounts";
        File file = new File(filePath);
        List<String> lineList = new ArrayList<>();
        InputStream inputStream =null;
        try {
            inputStream = new FileInputStream(file);
            if (inputStream != null) {
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                    if (line.contains("vfat")) {
                        lineList.add(line);
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if (lineList.isEmpty()){
            Log.i(HEAD, "getUDiskPath no usb disk ");
            return "";
        }
        String editPath = lineList.get(lineList.size() - 1);

        Log.i(HEAD,"edit path = " + editPath);
        int start = editPath.indexOf("/mnt");
        int end = editPath.indexOf(" vfat");
        String path = editPath.substring(start, end);
        return path;
    }

生成你要复制或剪切到U盘的文件并获取其路径srcPath

拼接命令传入下面的执行命令方法中,其中isRooted需传入true

    /**
     * Execute the command.
     *
     * @param commands        The commands.
     * @param isRooted        True to use root, false otherwise.
     * @param isNeedResultMsg True to return the message of result, false otherwise.
     * @return the single {@link CommandResult} instance
     */
    public static CommandResult execCmd(final String[] commands,
                                        final boolean isRooted,
                                        final boolean isNeedResultMsg) {
        int result = -1;
        if (commands == null || commands.length == 0) {
            return new CommandResult(result, null, null);
        }
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;
        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(isRooted ? "su" : "sh");
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) continue;
                os.write(command.getBytes());
                os.writeBytes(LINE_SEP);
                os.flush();
            }
            os.writeBytes("exit" + LINE_SEP);
            os.flush();
            result = process.waitFor();
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(new InputStreamReader(process.getInputStream(),
                        "UTF-8"));
                errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream(),
                        "UTF-8"));
                String line;
                if ((line = successResult.readLine()) != null) {
                    successMsg.append(line);
                    while ((line = successResult.readLine()) != null) {
                        successMsg.append(LINE_SEP).append(line);
                    }
                }
                if ((line = errorResult.readLine()) != null) {
                    errorMsg.append(line);
                    while ((line = errorResult.readLine()) != null) {
                        errorMsg.append(LINE_SEP).append(line);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (successResult != null) {
                    successResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(
                result,
                successMsg == null ? null : successMsg.toString(),
                errorMsg == null ? null : errorMsg.toString()
        );
    }

例如

/**源文件*/
String srcPath = "/storage/emulated/0/test.txt";
/**目标位置,如U盘跟路径*/
String targetPath = getUDiskRealPath();
/**拼接复制命令*/
String cmd = "cp -r " + srcPath + " " + targetPath;
/**执行复制命令*/
execCmd(new String[]{cmd},true,true);

即可完成文件写在U盘根目录(或者其他目录)的操作。

写文件会了,读文件也就是反过来进行了,先复制或剪切文件到内置存储卡,在进行基本的文件操作即可。

猜你喜欢

转载自blog.csdn.net/Panda_Kill/article/details/106923326
OTG