Как проверить, нужны ли элементы в getPersistedUriPermissions

При использовании getPersistedUriPermissions(), предполагая, что он уже содержит некоторые UriPermission, как узнать, являются ли они правильными разрешениями для того, что вы пытаетесь сделать?

Например, если вы получаете права на запись на SD-карту (или область SD-карты), а пользователь заменяет SD-карту на другую, эти разрешения больше не действительны. Как вы можете проверить, являются ли разрешения в списке, возвращенном функцией, пригодными для использования или нет (что требует от вас повторного запроса разрешения)?

Раньше я просто проверял, есть ли у меня хотя бы одно разрешение, но это больше не работает, когда они используют несколько SD-карт и т. Д. Однако я не вижу способа определить, является ли UriPermission в списке тем, что мне нужно. Пример один:

UriPermission {uri=content://com.android.externalstorage.documents/tree/abcdef, modeFlags=3, persistedTime=abcdef}

person David    schedule 17.12.2015    source источник


Ответы (2)


Это еще не сильно проверено. Я все еще работаю над тонкостями (читай: огромными дырами в дизайне) Document API.

/**
 * Returns the permissible root uri if one exists, null if not.
 *
 * @return The tree URI.
 */
public Uri getPermissibleRoot(Uri uri)
{
    if (uri == null)
        return null;

    for (UriPermission permission : mRootPermissions)
    {
        // TODO: This will not work with file schemes, there might not be a way to do so...
        String permissionTreeId = DocumentsContract.getTreeDocumentId(permission.getUri());
        String uriTreeId = DocumentsContract.getTreeDocumentId(uri);

        if (uriTreeId.startsWith(permissionTreeId))
        {
            return permission.getUri();
        }
    }

    return null;
}

Это часть библиотеки Android, над которой я работаю. Он еще далеко не готов к прайм-тайму, но я надеюсь упростить работу с Document API:

https://github.com/rcketscientist/DocumentActivity

person Anthony    schedule 02.02.2016
comment
Я тоже только что наткнулся на это. Uris, возвращенные из PersistedUriPermissions, не совсем совпадают с Uris, отправленными через TakePersistableUriPermission. - person joe; 26.05.2019
comment
@Джо действительно. Именно поэтому решение Энтони работает - идентификаторы, возвращаемые DocumentsContract.getTreeDocumentId, являются номинальными и могут быть правильно сопоставлены на предмет равенства (или, в его случае, проверки родительскости) - person Paul W; 21.04.2020

Вы должны использовать getPersistedUriPermissions() для проверки разрешений следующим образом:

private boolean checkStoragePermissions(){
        List<UriPermission> list = getContentResolver().getPersistedUriPermissions();
        for (int i = 0; i < list.size(); i++){

            if(list.get(i).getUri() == myUri && list.get(i).isWritePermission()){
                return true;
            }

        }

        return false;
    }

например, где myUri может быть uri на установленной в данный момент SD-карте.

Обратите внимание, что getUri() возвращает Uri, но с добавленным content://com.android.externalstorage.documents/tree/, и также будет соответствовать RFC 2396.

Пример: я выбираю папку с именем «xyz» на своей SD-карте, поэтому getUri() вернет что-то вроде этого: content://com.android.externalstorage.documents/tree/3142-4535%3Axyz

person Pete    schedule 01.06.2016
comment
Разве сравнение не должно быть list.get(i).getUri().equals(myUri)? - person Peter Tran; 09.06.2016