繁体   English   中英

如何在Android中获取外部USB大容量存储路径?

[英]How to get external usb mass storage path in Android?

我需要从/向 U 盘导入/导出一些数据。 有没有办法获取已挂载的 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 大容量存储设备时应用程序处于前台,则此方法可以正常工作。 如果您想知道,是的,Android 设备有多个 USB 端口。

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

更新 1:

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

更新 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);

这不会显示 U 盘,我也无法过滤文件和文件夹。 选择文档树

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

ES Datei 浏览器

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

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

所以我搜索了很多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 ,但仅此而已。

因此,查看/proc/mounts 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

在现代 Android 系统上几乎没有路径。 如今,您将尝试获得一个文档树方案。

有几种选择。

您可以查看getExternalFilesDirs()返回的第二个或第三个项目。 (将给出一条路径。但无法写入。)

对于 Android 6+,使用 Intent.ACTION_OPEN_DOCUMENT_TREE 让用户选择驱动器。 这会给你一个内容方案。 没有文件路径。

对于 Android 7+,请查看Storage Volumes

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM