Создание Uri для Android 5.0 DocumentFile из корневого URI ACTION_OPEN_DOCUMENT_TREE

Я могу успешно получить URI базового пути из OPEN_DOCUMENT_TREE из инфраструктуры доступа к хранилищу.

Как использовать новый API доступа к SD-карте, представленный для Android 5.0 (Lollipop)?

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, которая нарушает рекурсию, как указано в этом посте:

Ошибка при выводе списка файлов с платформой Android Storage Access на Lollipop

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

Использование File.listFiles() возвращает пустой массив.

Я уже знаю полный путь к целевым папкам / файлам. Я хотел бы создать действительный URI DocumentFile, который имеет полномочия корневого Uri, возвращенного в onActivityResult.

Я хотел бы добавить к корневому пути Uri или создать новый Uri, который имеет те же разрешения, что и корневой Uri, для доступа к целевым папкам / файлам.

1 ответ

Вы в основном хотите нарезать и нарезать отрезками пути URI. Вы также хотите избежать вызова findFile. Его производительность отрицательно зависит от размера папки. Сотни файлов могут означать несколько секунд, и это продолжает расти.

Моим решением было обернуть DocumentFile правильно работающим getParent. Я еще не совсем закончил (то есть: этот код не полностью функционален), но он может указать вам, как манипулировать Uris для ваших целей.

/**
 *  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);
}

Еще раз, это еще не полностью функционально, но оно может указать вам правильное направление. Я буду обновлять, когда я разобрался со всеми изломами.

Другие вопросы по тегам