无法访问Android上的外部sd卡



我可以使用轻松访问内部存储文件

File internalStorage = new File( Environment.getExternalStorageDirectory().getAbsolutePath() );     
internalStorage.listFiles();

我正在获取所有的文件。但是我无法从我安装的sd卡中获取任何文件。我查过了。如果SD卡已安装

boolean isSdCard = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);

我也尝试过不同的解决方案,比如。

File sdCardFolder = new File(System.getenv("SECONDARY_STORAGE"));   
//RESULT.    
sdCardFolder.getName() //sdcard0.   
sdCardFolder.listFile() //null.

在这里,它给出了文件夹名称,但为listFile发送了null。

此外,我还尝试了其他不同的方法来从我的SD卡中列出文件,但找不到一个有效的方法。

在build.gradle.中

compileSdkVersion 31.    
targetSdkVersion 31

检查并请求允许访问清单中的外部卡或通过代码

为了补充@Saqib的答案,我简化了代码,不需要使用他的助手/包装器类。

StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
List<StorageVolume> storageArray = storageManager.getStorageVolumes();
String path = "";
for (StorageVolume item : storageArray)
if (item.isRemovable())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
path = item.getDirectory().getPath();

要处理null情况,只需检查路径字符串是空的还是null,然后进行适当的处理。

经过大量的研究和时间,我终于找到了问题的解决方案。有很多问题都在问同一个问题,但在我曝光之前,没有任何相关的有效解决方案。

我回答自己的问题是为了帮助其他面临同样问题的人。我使用以下代码来获取SD卡的路径。然后我正常访问了它,就像我访问了安卓设备的内部存储一样。

// The following function will return the path of the SD card
// or NULL, if no SD card is mounted.
public static String getExternalStoragePath(Context mContext, boolean is_removable) {
StorageManager mStorageManager = 
(StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (is_removable == removable) {
return path;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}

最新更新