0

我可以从 Storage Access Framework 的 OPEN_DOCUMENT_TREE 成功获取基本路径 Uri。

如何使用为 Android 5.0 (Lollipop) 提供的新 SD 卡访问 API?

private static final int READ_REQUEST_CODE = 42;

public void performFileSearch() {

    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);

    startActivityForResult(intent, READ_REQUEST_CODE);
}


@Override
public void onActivityResult(int requestCode, int resultCode,
                             Intent resultData) {

    // The ACTION_OPEN_DOCUMENT intent was sent with the request code
    // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
    // response to some other intent, and the code below shouldn't run at all.

    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        // The document selected by the user won't be returned in the intent.
        // Instead, a URI to that document will be contained in the return intent
        // provided to this method as a parameter.
        // Pull that URI using resultData.getData().
        Uri uri = null;
        if (resultData != null) {
            uri = resultData.getData();

        }
    }
}

但是 android 5.0 中有一个错误/功能会破坏本文中引用的递归:

在 Lollipop 上使用 Android 存储访问框架列出文件时出现错误

Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
Uri f1 = pickedDir.findFile("MyFolder").getUri();
Log.d(TAG, "f1 = " + f1.toString());

使用 File.listFiles() 返回一个 Null 数组。

我已经知道目标文件夹/文件的完整路径。我想构造一个有效的 DocumentFile Uri,它具有 onActivityResult 中返回的根 Uri 的权限。

我想附加到根 Uri 路径或构建一个与根 Uri 具有相同权限的新 Uri 以访问目标文件夹/文件。

4

1 回答 1

0

您基本上想要对 uri 的路径段进行切片和切块。您还希望避免调用 findFile。它的性能与文件夹大小成负相关。数百个文件可能意味着几秒钟,而且还在不断增加。

我的解决方案是使用功能正常的 getParent 包装 DocumentFile。我还没有完全完成(即:此代码功能不完整),但它可能会为您指明如何操作 uri 以实现您的目标。

/**
 *  Uri-based DocumentFile do not support parent at all
 *  Try to garner the logical parent through the uri itself
 * @return
 */
protected UsefulDocumentFile getParentDocument()
{
    Uri uri = mDocument.getUri();
    String documentId = DocumentsContract.getDocumentId(uri);

    String[] parts = getPathSegments(documentId);

    if (parts == null)
        return null;

    Uri parentUri;
    if (parts.length == 1)
    {
        String parentId = DocumentsContract.getTreeDocumentId(uri);
        parentUri = DocumentsContract.buildTreeDocumentUri(uri.getAuthority(), parentId);
    }
    else
    {
        String[] parentParts = Arrays.copyOfRange(parts, 0, parts.length - 2);
        String parentId = TextUtils.join(URL_SLASH, parentParts);
        parentUri = DocumentsContract.buildTreeDocumentUri(uri.getAuthority(), parentId);
    }

    return UsefulDocumentFile.fromUri(mContext, parentUri);
}

再一次,这还没有完全发挥作用,但它可能会为您指明正确的方向。当我解决所有问题时,我会更新。

于 2016-01-27T11:41:03.093 回答