我正在让用户使用存储访问框架文档选择内部存储或外部存储(SD 卡)。
在用户选择目录后,我想检查用户选择的目录是否属于特定存储(内部或外部存储)的根文件夹。
这就是我努力实现这一目标的方式,这就是我到目前为止所取得的成就-
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == 42) {
Uri treeUri = data.getData();
if (!wrong_directory_selected(treeUri, Context)) {
// Permission granted for the Directory as required by me
} else {
// Permission not granted for the Directory as required by me
}
}
}
}
public boolean wrong_directory_selected(Uri uri, Context con)
{
final File uri_path=new File(FileUtil.getFullPathFromTreeUri(uri,con.getApplicationContext()));
if(uri_path!=null)
{
if(uri_path.getName().toLowerCase().equals(new File(PathForWhichPermissionNeeded).getName().toLowerCase()))
{
return false;
}
}
return true;
}
这是我的 FileUtil
类-
public final class FileUtil {
private static final String PRIMARY_VOLUME_NAME = "primary";
@Nullable
public static String getFullPathFromTreeUri(@Nullable final Uri treeUri, Context con)
{
if (treeUri == null)
{
return null;
}
String volumePath = getVolumePath(getVolumeIdFromTreeUri(treeUri),con);
if (volumePath == null)
{
return File.separator;
}
if (volumePath.endsWith(File.separator))
{
volumePath = volumePath.substring(0, volumePath.length() - 1);
}
String documentPath = getDocumentPathFromTreeUri(treeUri);
Log.e("DocumentPath",documentPath);
if (documentPath.endsWith(File.separator))
{
documentPath = documentPath.substring(0, documentPath.length() - 1);
}
if (documentPath.length() > 0)
{
if (documentPath.startsWith(File.separator))
{
return volumePath + documentPath;
}
else {
return volumePath + File.separator + documentPath;
}
}
else
{
return volumePath;
}
}
private static String getVolumePath(final String volumeId, Context con)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
{
return null;
}
try {
StorageManager mStorageManager =
(StorageManager) con.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getUuid = storageVolumeClazz.getMethod("getUuid");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isPrimary = storageVolumeClazz.getMethod("isPrimary");
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 uuid = (String) getUuid.invoke(storageVolumeElement);
Boolean primary = (Boolean) isPrimary.invoke(storageVolumeElement);
// primary volume?
if (primary && PRIMARY_VOLUME_NAME.equals(volumeId))
{
return (String) getPath.invoke(storageVolumeElement);
}
// other volumes?
if (uuid != null)
{
if (uuid.equals(volumeId))
{
return (String) getPath.invoke(storageVolumeElement);
}
}
}
// not found.
return null;
}
catch (Exception ex)
{
return null;
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getVolumeIdFromTreeUri(final Uri treeUri)
{
final String docId = DocumentsContract.getTreeDocumentId(treeUri);
final String[] split = docId.split(":");
if (split.length > 0)
{
return split[0];
}
else
{
return null;
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getDocumentPathFromTreeUri(final Uri treeUri)
{
final String docId = DocumentsContract.getTreeDocumentId(treeUri);
final String[] split = docId.split(":");
if ((split.length >= 2) && (split[1] != null))
{
return split[1];
}
else
{
return File.separator;
}
}
}
所以基本上 onActivityResult
我正在检查所选目录路径的 treeuri
是否等于我需要的路径。
这是所选目录content://com.android.externalstorage.documents/tree/primary%3A
treeuri
这是从上面的 treeuri
/storage/sdcard0
返回的路径
预期返回的路径是/storage/sdcard1
。
因此,即使选择了正确的目录,也会返回错误的路径。
谁能帮我找到treeuri
的确切路径或者谁能帮我检查treeuri
是属于内部存储还是外部存储(SD卡) .
最佳答案
I want to check if the Directory selected by the user is of the Root folder of the particular Storage( Internal or External Storage).
欢迎您对 DocumentFile
使用 getParentFile()
,并查看它返回文档树顶部的内容。他们没有记录这里到底发生了什么,但它应该返回 null
或抛出某种异常。然后,您可以使用它来确定返回的文档树是否恰好是某物的根。
但是,没有要求“某物”是external storage或 removable storage .用户可以从 Google Drive、Windows 文件服务器或任意数量的其他数据源中选择文档树。不要求您能够识别数据源的来源。
And this is my FileUtil class
该类中的许多代码都做出了无效的假设。其余的使用反射,很有可能 the next version of Android will ban access to hidden APIs using reflection .
Can anyone help me to find the exact path of the treeuri
没有“treeuri 的确切路径”。
Can anyone help me to check if the treeuri belongs to Internal Storage or External Storage (SD Card)
这在一般情况下是不可能的。
关于java - 从 Uri 获取路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48461317/