Rah*_*602 7 java android uri file storage-access-framework
我正在让用户使用存储访问框架文档选择存储内部或外部存储(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;
}
Run Code Online (Sandbox Code Playgroud)
这是我的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上onActivityResult我正在检查treeuri所选目录路径中是否与我所需的路径相等.
这是treeuri所选目录的content://com.android.externalstorage.documents/tree/primary%3A
这是从上面返回的路径 treeuri /storage/sdcard0
预期返回的路径是/storage/sdcard1.
因此,即使选择了正确的目录,也会返回错误的路径.
任何人都可以帮我找到确切的路径treeuri或任何人可以帮助我检查是否treeuri属于内部存储或外部存储(SD卡).
我想检查用户选择的目录是否属于特定存储(内部或外部存储)的根文件夹.
欢迎您使用getParentFile()on DocumentFile,并查看文档树顶部返回的内容.他们没有准确记录这里发生的事情,但它应该返回null或抛出某种异常.然后,您可以使用它来确定返回的文档树是否恰好是某个东西的根.
但是,并不要求"某物"是外部存储或可移动存储.用户可以从Google Drive,Windows文件服务器或任意数量的其他数据源中选择文档树.您无需确定数据源的来源.
这是我的FileUtil类
该类中的大部分代码都会产生无效的假设.其余的使用反射,很有可能下一个版本的Android将禁止使用反射访问隐藏的API.
任何人都可以帮我找到树木的确切路径
没有"树木的确切路径".
任何人都可以帮我检查一下treeuri是属于内部存储还是外部存储(SD卡)
这一般是不可能的.