如何获取安卓机顶盒上已连接USB设备的存储信息
Hey there! Let's tackle this problem step by step since you're new to Android development. You already have the USB connect/disconnect events covered with a Broadcast Receiver, but getting the storage details requires a bit more work because USB storage has its own system broadcasts and APIs to access its info. Here's how you can do it:
When a USB storage device is connected to your set-top box, the Android system sends a ACTION_MEDIA_MOUNTED broadcast once the device is successfully mounted. Similarly, ACTION_MEDIA_UNMOUNTED is sent when it's disconnected.
Since Android 8.0 (API level 26), statically registered receivers can't catch most implicit broadcasts, so we'll use dynamic registration in your Activity/Fragment:
private BroadcastReceiver storageBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) { // USB storage is mounted, now fetch its details handleMountedStorage(intent, context); } else if (Intent.ACTION_MEDIA_UNMOUNTED.equals(action)) { // USB storage is unmounted, clean up if needed String unmountedPath = intent.getData().getPath(); Log.d("USB_STORAGE", "Unmounted USB device at: " + unmountedPath); } } }; // Register the receiver in onCreate() @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter storageFilter = new IntentFilter(); storageFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); storageFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); storageFilter.addDataScheme("file"); // Critical to receive the broadcast registerReceiver(storageBroadcastReceiver, storageFilter); } // Don't forget to unregister in onDestroy() to avoid leaks @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(storageBroadcastReceiver); }
To get details like total space, free space, and mount path (especially for multiple USB devices), use the StorageManager API—it's the most reliable way to access all mounted storage volumes on Android.
Add this method to handle mounted storage:
private void handleMountedStorage(Intent intent, Context context) { StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // For Android 11+ (API 30 and above) List<StorageVolume> storageVolumes = storageManager.getStorageVolumes(); for (StorageVolume volume : storageVolumes) { // USB storage is almost always removable if (volume.isRemovable()) { String volumeName = volume.getDescription(context); File volumeDirectory = volume.getDirectory(); if (volumeDirectory != null) { long totalSpace = volumeDirectory.getTotalSpace() / (1024 * 1024); // Convert to MB long freeSpace = volumeDirectory.getFreeSpace() / (1024 * 1024); Log.d("USB_STORAGE", "Device Name: " + volumeName); Log.d("USB_STORAGE", "Mount Path: " + volumeDirectory.getAbsolutePath()); Log.d("USB_STORAGE", "Total Space: " + totalSpace + " MB"); Log.d("USB_STORAGE", "Free Space: " + freeSpace + " MB"); } } } } else { // For Android 10 and below Uri storageUri = intent.getData(); String mountPath = storageUri.getPath(); File usbStorage = new File(mountPath); // Verify it's a removable storage device if (Environment.isExternalStorageRemovable(usbStorage)) { long totalSpace = usbStorage.getTotalSpace() / (1024 * 1024); long freeSpace = usbStorage.getFreeSpace() / (1024 * 1024); Log.d("USB_STORAGE", "Mount Path: " + mountPath); Log.d("USB_STORAGE", "Total Space: " + totalSpace + " MB"); Log.d("USB_STORAGE", "Free Space: " + freeSpace + " MB"); } } }
To access storage details, you need to request the appropriate permissions:
- Android 6.0 to Android 10 (API 23-29): Request
READ_EXTERNAL_STORAGEpermission dynamically. - Android 11+ (API 30+): If you need to access files on the USB drive, you'll need the
MANAGE_EXTERNAL_STORAGEpermission. Note that this requires the user to manually enable it in Settings > Apps > Your App > Permissions > Files and media.
Here's a quick snippet to request READ_EXTERNAL_STORAGE:
private static final int REQUEST_STORAGE_PERMISSION = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Check and request permission if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_STORAGE_PERMISSION); } // Register broadcast receiver... } // Handle permission result @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_STORAGE_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted, you can now access storage details } else { // Permission denied, show a message to the user Toast.makeText(this, "Storage permission is required to access USB details", Toast.LENGTH_SHORT).show(); } } }
- Multiple USB Devices: The
StorageManager.getStorageVolumes()method returns all mounted volumes, including internal storage and multiple USB drives. UsingisRemovable()ensures you only target USB devices. - Avoid Deprecated APIs: Don't rely on
Environment.getExternalStorageDirectory()—it only returns the default external storage and won't work for multiple USB devices. - Testing: Make sure your USB drive is formatted in a compatible filesystem (like FAT32 or NTFS, though NTFS support depends on the set-top box's Android version).
内容的提问来源于stack exchange,提问作者Deepak

