You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何播放连接USB设备中的视频及解决USB路径获取权限异常

问题1:如何播放已连接USB设备中的视频?

要播放USB设备里的视频,核心是先拿到合法的访问权限和正确的文件路径,步骤如下:

  • 先确认USB设备已挂载
    Android系统里,USB存储通常会被挂载到/storage/XXXX-XXXX这类路径(XXXX是设备的唯一标识UUID)。你可以通过遍历/storage/目录下的子文件夹找到它,或者让用户通过系统的**存储访问框架(SAF)**手动选择USB存储的文件夹,这样能更稳妥地拿到访问权限。

  • 定位到视频文件
    找到USB挂载路径后,遍历里面的文件,筛选出.mp4.avi.mkv等格式的视频文件,记录下完整的文件路径。

  • 用播放器实现播放
    你可以用系统自带的MediaPlayer快速实现,或者用更强大的ExoPlayer(支持更多格式和播放场景)。给你一个MediaPlayer的简单示例:

    MediaPlayer mediaPlayer = new MediaPlayer();
    try {
        // 替换成你找到的USB视频文件路径
        mediaPlayer.setDataSource("/storage/XXXX-XXXX/Movies/your_video.mp4");
        mediaPlayer.prepare();
        mediaPlayer.start();
    } catch (IOException e) {
        e.printStackTrace();
        // 这里可以添加播放失败的提示逻辑
    }
    

问题2:解决USB存储读取时的FileNotFoundException: open failed: EACCES错误

你碰到的这个权限错误,主要是Android的存储权限机制和USB设备的特殊访问规则导致的,结合你提到的CheckForSDCard().isSDCardPresent()代码,给你几个针对性的解决思路:

  • 先检查权限申请是否到位
    Android 6.0+需要动态申请READ_EXTERNAL_STORAGE权限,但USB存储可能不属于系统默认的"外部存储"范畴,所以光靠这个权限可能不够。如果是Android 10及以上,还要注意分区存储的限制——直接访问非应用私有目录的文件会被限制。

  • 改用存储访问框架(SAF)获取路径
    这是目前最稳妥的方式,让用户手动选择USB存储的文件夹,从而获得合法的访问权限:

    // 启动选择目录的Intent
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, REQUEST_PICK_USB_FOLDER); // REQUEST_PICK_USB_FOLDER是自定义的请求码
    

    然后在onActivityResult(或者AndroidX的registerForActivityResult)里拿到返回的Uri,再通过DocumentFile来操作文件,这样就能避开权限问题。

  • 修复CheckForSDCard.isSDCardPresent()的逻辑
    很多旧的SD卡检测方法只识别内置SD卡,不会把USB存储算进去。比如它可能只是判断Environment.getExternalStorageState()是否为MEDIA_MOUNTED,但USB存储的挂载路径不在默认的外部存储目录里,所以这个判断会返回false,导致后续代码逻辑出错。你可以修改这个方法,遍历/storage/目录下的所有挂载点来识别USB设备:

    public boolean isUSBStoragePresent() {
        File storageDir = new File("/storage/");
        File[] volumes = storageDir.listFiles();
        if (volumes != null) {
            for (File volume : volumes) {
                // 排除系统目录,判断是否为可访问的USB存储
                if (volume.isDirectory() && !volume.getName().equals("emulated")) {
                    return true;
                }
            }
        }
        return false;
    }
    
  • 如果是USB Host模式,要申请设备权限
    如果你是通过USB Host模式连接的设备(不是通过MTP挂载的),还需要通过UsbManager请求设备访问权限:

    UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    UsbDevice targetUsbDevice = ...; // 找到你要访问的USB设备
    PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent("com.your.app.USB_PERMISSION"), 0);
    usbManager.requestPermission(targetUsbDevice, permissionIntent);
    

    然后注册一个广播接收器,处理权限授予的结果,之后才能正常访问USB设备的内容。


内容的提问来源于stack exchange,提问作者Chetan Shelake

火山引擎 最新活动