Поставщик доступа к хранилищу - создание папки в авторизованном каталоге не удается - PullRequest
0 голосов
/ 08 июля 2019

Мое приложение позволяет пользователю создать папку с помощью средства выбора SAF, а затем хочет создать в ней папку.

Вот как называется сборщик:

static public void openPickerForFolderCreation(Activity activity,int requestCode)
{

    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.setType("vnd.android.document/directory");
    intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    activity.startActivityForResult(intent, requestCode);
}

В методе onActivityResult вызывается следующий код:

static public String takePermanentReadWritePermissions(Activity activity, Intent data)
{
    int takeFlags = data.getFlags()
            &
            (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    ContentResolver resolver = activity.getContentResolver();
    resolver.takePersistableUriPermission(data.getData(),takeFlags);
    return data.getData().toString();

}

Вот как проверяются разрешения (а в моем случае это так):

static boolean arePermissionsGranted(Activity activity, String uriString)
{
    ContentResolver resolver = activity.getContentResolver();
    List<UriPermission> list = resolver.getPersistedUriPermissions();
    for (int i = 0; i < list.size(); i++){
        if(((Uri.decode(list.get(i).getUri().toString())).equals( uriString)) && list.get(i).isWritePermission()&& list.get(i).isReadPermission()){
            return true;
        }
    }
    return false;
}

Затем приложение пытается создать папку в авторизованном каталоге (папке) с помощью:

static public boolean creatFolderInFolder(Activity activity,String parentFolderUriString,String folderName)
{
boolean result=false;
ContentResolver contentResolver;
contentResolver = activity.getContentResolver();
Uri parentFolderUri=null;
parentFolderUri= DocumentsContract.buildDocumentUri(PROVIDER_AUTHORITY,
        DocumentsContract.getDocumentId(Uri.parse(parentFolderUriString)));
try {
    DocumentsContract.createDocument(contentResolver,parentFolderUri,DocumentsContract.Document.MIME_TYPE_DIR,folderName);
            result=true;
} catch (FileNotFoundException e) {
    result =false;
}
return result;
}
}

Но если родительская папка была создана на диске, я получаю:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.app/com.mydomain.app.activityName}: java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.docs.storagebackend.StorageBackendContentProvider from ProcessRecord{f114a14 18915:com.mydomain.app/u0a412} (pid=18915, uid=10412) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

в то время как если родительская папка была создана в облачном пространстве GDrive (доступной из средства выбора), я получаю:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.app/com.mydomain.app.activityName}: java.lang.SecurityException: Permission Denial: writing com.google.android.apps.docs.storagebackend.StorageBackendContentProvider uri content://com.google.android.apps.docs.storage/document/acc%3Drandomcharactershere from pid=20197, uid=10413 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()

Они не являются исключениями, ошибка выдается по следующей строке:

DocumentsContract.createDocument(contentResolver,parentFolderUri,DocumentsContract.Document.MIME_TYPE_DIR,folderName);

SAF работает правильно? Кажется, я все сделал правильно в коде приложения, так почему я получаю эти ошибки?

...