2

给定 aFile或 a Uri,我如何可靠地确定文件是否位于连接到手机 USB 端口的 USB 大容量存储设备上?

我的测试手机是三星 Galaxy S7 Edge,它连接了一个 USB 大容量存储设备、一个内部(物理)微型 SD 卡和内部存储。当我查询时Context.getExternalCacheDirs(),我看到所有三个:

/storage/emulated/0/Android/data/...
/storage/A2B3-15F3/Android/data/...
/storage/3535-3038/Android/data/...

如何确定哪一个是 USB 大容量存储设备?(顺便说一句,它是 A2B3-15F3)。


研究

我查看了这个答案StorageHelper.resolveType()方法),但如您所见,设备的挂载文件路径不包含字符串“usb”。

然后我尝试使用该StorageManager服务。使用上面的设备,我们可以使用以下方法获取 StorageVolume`:

StorageManager storageManager = context.getSystemService(StorageManager.class);
StorageVolume volume = storageManager.getStorageVolume(context.getExternalCacheDirs()[1]);

这就是事情变得有点奇怪的地方。StorageVolumeAPI 文档和我在 Android 25 源中的文件的本地副本似乎对我没有太大帮助,但是当我在 Android Studio 调试器中执行上述代码时,该对象包含一个mSubSystem将上述三个设备描述为的字段“保险丝”,“usb”和“sd”分别。这是一个例子:

Android Studio 调试器的屏幕截图,显示 USB 大容量存储设备的 StorageVolume

为什么我在调试器中看到此信息,而不是源代码?此字段是否特定于此特定手机的 Android 发行版?

4

2 回答 2

0

Environment.getExternalStorageDirectory()将返回 SD 卡挂载点的路径。只有极少数设备(支持USB 主机模式用于外部存储的设备)支持 USB 存储。这将安装在 下的某个/mnt位置,但具体位置会有所不同。您将需要使用 Android NDK 来询问和迭代已安装的设备以找到您想要的设备。在NDK&query里面写逻辑/mnt是一条靠谱的路线。

如果您真的想在 java 端尝试,请尝试以下代码,如果它适合您:

public String getUSBStoragepath() {
    try {
        Runtime runtime = Runtime.getRuntime();
        Process proc = runtime.exec("mount");
        InputStream input_stream = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader(input_stream);
        String line;
        String[] paths_list = new String[10];
        int i = 0;
        int available = 0;

        BufferedReader buffer_reader = new BufferedReader(isr);
        while ((line = buffer_reader.readLine()) != null) {
            String mount = new String();
            if (line.contains("secure"))
                continue;
            if (line.contains("asec"))
                continue;

            if (line.contains("fat")) {// TF card
                String columns[] = line.split(" ");
                if (columns != null && columns.length > 1) {
                    mount = mount.concat(columns[1] + "/requiredfiles");

                    paths_list[i] = mount;
                    i++;

                    // check directory is exist or not
                    File dir = new File(mount);
                    if (dir.exists() && dir.isDirectory()) {
                        // do something here

                        available = 1;
                        final_path = mount;
                        break;
                    } else {

                    }
                }
            }
        }
        if (available == 1) {

        } else if (available == 0) {
            final_path = paths_list[0];
        }

    } catch (Exception e) {

    }
    return final_path;
}

然后,您需要在最终路径中查询以查看相关文件是否存在,以确定给定文件是否在 USB 中。

于 2017-05-17T18:20:32.320 回答
0

您可以通过USBManager检查USB大容量存储是否连接到手机,连接的USB设备列表,然后检查USBInterface是否为USB_CLASS_MASS_STORAGE。然后要求用户断开 USB 大容量存储,保存 SD 卡路径并要求用户重新连接 USB。其余目录将是 USB 路径。

于 2018-02-06T14:50:15.537 回答