4

我需要从 / 到 USB 棒导入/导出一些数据。有没有办法获取已安装的 USB 设备的路径?

我的代码看起来像这样:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

while(deviceIterator.hasNext()){

    UsbDevice device = deviceIterator.next();
    UsbInterface deviceInterface = device.getInterface(0);

    if(deviceInterface != null && deviceInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE){
        // check if path "mnt/usb_storage/*" exist
    }
}

当设备为大容量存储时,我可以搜索路径“mnt/usb_storage/*”是否存在。如果仅连接了一个 USB 大容量存储器,或者当连接了第二个 USB 大容量存储器时应用程序处于前台,则此方法可以正常工作。如果您想知道,是的,有多个 USB 端口的 Android 设备。

当我有 UsbManager/UsbDevice/UsbInterface 时,是否无法获取路径?所有设备上的路径都像“mnt/usb_storage/*”吗?

更新1:

目标 Android 版本 5.1 要求:必须在应用程序中集成“文件选择器”,必须应用文件夹过滤器、文件名和文件类型。

更新 2:

正如@greenapps 所建议的,我尝试了“ACTION_OPEN_DOCUMENT_TREE”:

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
intent.putExtra("android.content.extra.FANCY", true);
intent.putExtra("android.content.extra.SHOW_FILESIZE", true);
startActivityForResult(intent, OPEN_DOCUMENT_TREE_REQUEST_CODE);

这没有显示 USB 棒,我也无法过滤文件和文件夹。 选择文档树

相同设备:es-datei explorer 能够显示 USB 设备。

ES Datei explorer

我的要求是显示一个自定义文件选择器,用户可以在其中从客户特定的云、内部存储或类似于 es datei explorer 的 USB 设备中选择文件。

我搜索路径是否存在的解决方案:“mnt/usb_storage/*”存在按要求工作我只是想知道是否有更好的方法。

4

2 回答 2

4

因此,我搜索了很多 SO 问题以获取 USB 设备的路径。我还没有找到答案,但由于这是谷歌搜索的顶部和一个相当新的问题,我将发布我找到的内容。

尝试(充实)

所以最初我尝试(使用我自己的实现),因为问题包含:

public static String getUSBProblematic(Context context){
    UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
    if (usbManager == null) {
        Log.e(TAG, "Unable to get USB_SERVICE");
        return "";
    }
    UsbAccessory[] accessoryList = usbManager.getAccessoryList();
    if (accessoryList != null) {
        for (UsbAccessory usbAccessory : accessoryList) {
            // here we check the vendor
            Log.d(TAG, "getUSBProblematic: " + usbAccessory.toString());
        }
    }

    HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
    if(deviceList != null) {
        List<UsbDevice> usbDeviceList = new ArrayList<>(deviceList.values());

        for (Iterator<UsbDevice> iterator = usbDeviceList.iterator(); iterator.hasNext();) {
            UsbDevice next = iterator.next();

            boolean isMassStorage = false;
            for (int i = 0; i < next.getInterfaceCount(); i++) {
                // Check USB interface type is mass storage
                UsbInterface usbInterface = next.getInterface(i);
                if(usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE && usbInterface.getEndpointCount() == 2) {

                    // Check endpoints support bulk transfer
                    for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
                        UsbEndpoint endpoint = usbInterface.getEndpoint(j);
                        if(endpoint != null) {
                            if(endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK){

                                // Valid mass storage
                                isMassStorage = true;
                            }
                        }
                    }
                }
            }

            if(!isMassStorage) {
                iterator.remove();
            }
        }

        for (UsbDevice usbDevice : usbDeviceList) {
            Log.d(TAG, "getUSBProblematic: Device Name" + usbDevice.getDeviceName());
            Log.d(TAG, "getUSBProblematic: Device Desc" + usbDevice.toString());
        }
    }
    return "";
}

所以我能从中得到的最好的东西就是/dev/bus/usb/003,但仅此而已。

因此,查看我的mounts文件/proc/mounts(在设备上找到,请参阅Android Studio 中的设备文件资源管理器,我看到 USB 特定的存储设备安装在/mnt/media_rw/。但是浏览到/storage,我看到了我期望或正在寻找的 USB 设备。

我不确定这是否是一个好的策略或特定于设备(我使用的是华为 Mate 10 Pro),但我正在使用

可能的解决方案

public static String getUSB(){
    File storageDirectory = new File("/storage");
    if(!storageDirectory.exists()) {
        Log.e(TAG, "getUSB: '/storage' does not exist on this device");
        return "";
    }

    File[] files = storageDirectory.listFiles();
    if(files == null) {
        Log.e(TAG, "getUSB: Null when requesting directories inside '/storage'");
        return "";
    }

    List<String> possibleUSBStorageMounts = new ArrayList<>();
    for (File file : files) {
        String path = file.getPath();
        if (path.contains("emulated") ||
                path.contains("sdcard") ||
                path.contains("self")) {
            Log.d(TAG, "getUSB: Found '" + path + "' - not USB");
        } else {
            possibleUSBStorageMounts.add(path);
        }
    }

    if (possibleUSBStorageMounts.size() == 0) {
        Log.e(TAG, "getUSB: Did not find any possible USB mounts");
        return "";
    }
    if(possibleUSBStorageMounts.size() > 1) {
        Log.d(TAG, "getUSB: Found multiple possible USB mount points, choosing the first one");
    }

    return possibleUSBStorageMounts.get(0);
}

编辑 1

也可能有用(搜索USB

于 2019-12-18T15:00:15.213 回答
2

现代安卓系统大多没有路径。现在,您将尝试获取文档树方案。

有几种选择。

您可以查看由 . 返回的第二个或第三个项目getExternalFilesDirs()。(会给出一条路径。但不可能写。)

对于 Android 6+,使用 Intent.ACTION_OPEN_DOCUMENT_TREE 让用户选择驱动器。这将为您提供内容方案。没有文件路径。

对于 Android 7+,请查看Storage Volumes.

于 2018-08-15T08:53:56.303 回答