简体   繁体   English

从Uri获取路径

[英]Get path from Uri

I am making the User selects a Storage either Internal or External Storage(SD Card) using the Storage Access Framework Document. 我正在让用户使用存储访问框架文档选择存储内部或外部存储(SD卡)。

After the user selects the Directory I want to check if the Directory selected by the user is of the Root folder of the particular Storage( Internal or External Storage). 用户选择目录后,我想检查用户选择的目录是否属于特定存储(内部或外部存储)的根文件夹。

This is how I am trying to achieve this and this is what I have achieved till now- 这就是我试图实现这个目标的方法,这是我迄今为止所取得的成就 -

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;
    }

And this is my FileUtil class- 这是我的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;
        }
    }


}

So basically onActivityResult I am checking if the treeuri of the selected directory path is equal or not to the path required by me. 所以基本上onActivityResult我正在检查所选目录路径的treeuri是否与我所需的路径相等。

This is the treeuri for the selected directory content://com.android.externalstorage.documents/tree/primary%3A 这是treeuri所选目录content://com.android.externalstorage.documents/tree/primary%3A

This is the path which is being returned from the above treeuri /storage/sdcard0 这是从上面的treeuri /storage/sdcard0返回的路径

The path which is expected to be returned is /storage/sdcard1 . 预期返回的路径是/storage/sdcard1

So even after choosing the right directory the wrong path is being returned. 因此,即使选择了正确的目录,也会返回错误的路径。

Can anyone help me to find the exact path of the treeuri or Can anyone help me to check if the treeuri belongs to Internal Storage or External Storage (SD Card). 任何人都可以帮我找到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). 我想检查用户选择的目录是否属于特定存储(内部或外部存储)的根文件夹。

You are welcome to use getParentFile() on DocumentFile , and see what it returns for the top of the document tree. 欢迎您在DocumentFile上使用getParentFile() ,并查看它返回文档树顶部的内容。 They do not document exactly what happens here, but it should either return null or throw some sort of exception. 它们没有准确记录这里发生的事情,但它应该返回null或抛出某种异常。 You could then use that to determine whether the returned document tree happens to be a root of something. 然后,您可以使用它来确定返回的文档树是否恰好是某个东西的根。

However, there is no requirement that the "something" be external storage or removable storage . 但是,并不要求“某物”是外部存储可移动存储 The user could choose a document tree from Google Drive, or a Windows file server, or any number of other data sources. 用户可以从Google Drive,Windows文件服务器或任意数量的其他数据源中选择文档树。 There is no requirement that you be able to identify where the data source comes from. 您无需确定数据源的来源。

And this is my FileUtil class 这是我的FileUtil类

Much of the code in that class makes invalid assumptions. 该类中的大部分代码都会产生无效的假设。 The rest uses reflection, and it is quite possible that the next version of Android will ban access to hidden APIs using reflection . 其余的使用反射,很有可能下一个版本的Android将禁止使用反射访问隐藏的API

Can anyone help me to find the exact path of the treeuri 任何人都可以帮我找到树木的确切路径

There is no "exact path of the treeuri". 没有“树木的确切路径”。

Can anyone help me to check if the treeuri belongs to Internal Storage or External Storage (SD Card) 任何人都可以帮我检查一下treeuri是属于内部存储还是外部存储(SD卡)

That is not possible in general. 这一般是不可能的。

I want to check if the Directory selected by the user is of the Root folder of the particular Storage 我想检查用户选择的目录是否属于特定存储的根文件夹

That is very simple. 这很简单。 If the content scheme ends on %3A than it is. 如果内容方案以%3A结束,则结束。

So check data.getData().toString() for it. 所以检查data.getData().toString()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM