繁体   English   中英

打开外部“文件资源管理器”应用程序:如何从指向文件夹的 uri 获取绝对路径

[英]opening an external "file explorer" app: how to get absolute path from a uri pointing to a folder

在我的应用程序中,用户可以选择创建文件(文本文件)的位置。 这部分工作正常。 但是现在,我想打开一个外部“文件浏览器”应用程序,直接指向所选文件夹。 我知道的“文件资源管理器”应用程序接受绝对路径作为输入(例如/storage/emulated/0/Documents/test_folder

当用户选择一个文件夹(使用 Intent.ACTION_OPEN_DOCUMENT_TREE)时,我得到一个内容 uri(如content://com.android.externalstorage.documents/tree/home%3Atest_folder

另一个使用外部 SD 卡的例子:

  • uri: content://com.android.externalstorage.documents/tree/3877-DB74%3ADocuments%2Ftest_folder
  • 预期路径: /storage/3877-DB74/Documents/test_folder

uri 指向一个文件夹,而不是一个文件,所以我不能使用像 openInputStream 这样的东西

我努力了:

File f = new File(uri.getPath());
String path = f.getAbsolutePath();

但它给出: /tree/home:test_folder/tree/3877-DB74:Documents/test_folder如果在 sd 卡上

我怎样才能得到真正的绝对路径?

我用来调用文件资源管理器的代码:

Intent intent = new Intent(Intent.ACTION_VIEW);
String path = getExternalFilesDir(null).getAbsolutePath();
intent.setDataAndType(Uri.parse(path), "resource/folder");
if (intent.resolveActivityInfo(getPackageManager(), 0) != null)
{
    startActivity(intent);
}

所以基本上你想从 uri 获取文件路径

你试试这个代码

https://gist.github.com/pratikbutani/eb56f6f9f7013e31d8bfea9effbd4251

我已经尝试了建议的代码(见上文)。

不幸的是,我遇到了一个例外:

     Caused by: java.lang.UnsupportedOperationException: Unsupported Uri content://com.android.externalstorage.documents/tree/home%3Atest_folder
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
        at android.content.ContentResolver.query(ContentResolver.java:760)
        at android.content.ContentResolver.query(ContentResolver.java:710)
        at android.content.ContentResolver.query(ContentResolver.java:668)
        at ....UriUtils.getDataColumn(UriUtils.java:278)

这是代码的副本:

private static String getDataColumn(Context context, Uri uri)
{
    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = { column };

    try {
        cursor = context.getContentResolver().query(uri, projection, 
                                                    null, null, null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

我终于写了自己的方法来从 Uri 获取文件夹的绝对路径。 它肯定不是完全通用的,但它满足了我的需要。

如果它可以帮助某人,这是我的代码:

注意:VOLUME_MAP 是一个 map,包含所有已安装的外部卷

    /**************************************************************************/
    public static String getRealPathFromContentUri(final Uri uri)
    {
        if (!isExternalStorageDocument(uri))
        {
            return null;
        }

        List<String> segs = uri.getPathSegments();
        if (!"tree".equalsIgnoreCase(segs.get(0)))
        {
            return null;
        }

        String path = uri.getLastPathSegment();
        final String[] split = path.split(":");
        final String volumeId = split[0];
        String userPath = "";
        if (split.length > 1)
        {
            userPath = "/" + split[1];
        }
        if ("primary".equalsIgnoreCase(volumeId))
        {
            return Environment.getExternalStorageDirectory().getAbsolutePath() + userPath;
        }

        if ("home".equalsIgnoreCase(volumeId))
        {
            return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + userPath;
        }

        // look for real volumeId
        final String volumeName = VOLUME_MAP.get(volumeId);
        if (volumeName == null)
        {
            return null;
        }
        path = "/storage";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
        {
            path = Environment.getStorageDirectory().getAbsolutePath();
        }
        return path  + "/" + volumeId + userPath;
    }

感谢有关此主题的所有贡献者。

暂无
暂无

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

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