Android无需ACTION_OPEN_DOCUMENT_TREE自动访问USB存储实现文件备份
自动复制指定USB设备文件的实现方案
一、采用Android USB Host API直接访问目标U盘
由于你的设备是锁定状态的内部应用,无需遵循应用商店合规限制,可以通过USB Host API直接识别并访问名为Flash_1的U盘,跳过用户手动选择的步骤。
核心实现步骤
- 监听U盘插入事件
注册广播接收器监听系统发送的android.hardware.usb.action.USB_DEVICE_ATTACHED广播,当U盘插入时自动触发逻辑,过滤识别目标设备。 - 定位U盘挂载路径
通过读取/proc/mounts文件或执行mount命令,解析USB存储设备的挂载信息,匹配卷标为Flash_1的设备路径。示例代码片段:private String getFlash1MountPath() { try { BufferedReader reader = new BufferedReader(new FileReader("/proc/mounts")); String line; while ((line = reader.readLine()) != null) { // 过滤USB存储挂载项,适配vfat/exfat等常见U盘文件系统 if (line.contains("/dev/block/sd") && (line.contains("vfat") || line.contains("exfat"))) { String[] parts = line.split(" "); String mountPoint = parts[1]; if ("Flash_1".equals(getVolumeLabel(new File(mountPoint)))) { reader.close(); return mountPoint; } } } reader.close(); } catch (IOException e) { e.printStackTrace(); } return null; } private String getVolumeLabel(File mountDir) { try { Process process = Runtime.getRuntime().exec("mount"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { if (line.contains(mountDir.getAbsolutePath())) { int labelIndex = line.indexOf("label="); if (labelIndex != -1) { String labelPart = line.substring(labelIndex + 6); int endIndex = labelPart.indexOf(" "); return endIndex != -1 ? labelPart.substring(0, endIndex) : labelPart; } } } reader.close(); } catch (IOException e) { e.printStackTrace(); } return null; } - 后台执行文件复制
获取到U盘挂载路径后,使用普通File API递归遍历所有文件,复制到平板指定存储目录(如getExternalFilesDir(null))。注意必须在后台线程执行复制操作,避免ANR,可使用Coroutine或WorkManager实现。
二、权限与清单配置
在AndroidManifest.xml中添加必要权限和广播注册:
<!-- USB Host功能声明 --> <uses-feature android:name="android.hardware.usb.host" android:required="true" /> <!-- 存储访问权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 10+ 全文件访问权限 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" /> <!-- USB设备广播接收器 --> <receiver android:name=".UsbDeviceReceiver"> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" /> </intent-filter> <!-- 可选:添加U盘VID/PID过滤,精准识别目标设备 --> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" /> </receiver>
若需要精准过滤设备,在res/xml下创建usb_device_filter.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="你的U盘VID" product-id="你的U盘PID" /> </resources>
三、关键注意事项
- Android版本适配:Android 10及以上需手动开启
MANAGE_EXTERNAL_STORAGE权限,可预先在锁定设备上配置完成。 - 错误提示:添加未检测到目标U盘、复制失败等场景的用户提示(如Toast),确保技术小白能直观了解状态。
- 测试验证:在目标平板上使用实际的
Flash_1U盘测试,确保挂载路径识别和文件复制逻辑稳定。
内容的提问来源于stack exchange,提问作者Josh Hunter
相关产品推荐
相关产品推荐

