SAF - ошибка Uri при копировании файла из личной папки приложения в авторизованную папку SAF - PullRequest
1 голос
/ 28 сентября 2019

Мой Android должен скопировать файл из личной папки приложения в папку SAF, для которой ранее были предоставлены разрешения и авторизация.Код выглядит так:

static boolean copyDocumentFileToTargetFolderWithNewName(Activity activity, String docUri,String targetFolderUri,String newName)
{
    deleteIfExisting(activity,Uri.parse(targetFolderUri),newName);
    ContentResolver resolver = activity.getContentResolver();
    boolean result=false;
    Log.d("copy",docUri+" "+targetFolderUri+" "+newName);
    Log.d("doc exists",String.valueOf(fileExists(activity,docUri)));  //error here
    try {
        DocumentsContract.copyDocument(resolver,Uri.parse(docUri),Uri.parse(targetFolderUri));//or error here
        DocumentsContract.renameDocument(resolver,Uri.parse(docUri),newName);
        result=true;
    } catch (FileNotFoundException e) {
        result=false;
    }

    return result;
}

и

static public boolean fileExists(Activity activity,String fileUriString)
{
    ContentResolver contentResolver;
    contentResolver = activity.getContentResolver();
    String parentFolderUriString=StringUtils.fromLastSlashLeft(fileUriString);
    String fileName=StringUtils.fromLastSlashRight(fileUriString);
    Uri parentFolderUri=Uri.parse(parentFolderUriString);
    boolean exists;
    DocumentFile docFile=DocumentFile.fromTreeUri(activity,parentFolderUri).findFile(fileName); //error here
    exists= (null!=docFile);
    return exists;
}

(с некоторыми вызовами служебных строк, которые не требуют пояснений)

Здесь результат из строки Log.d ()

D/copy: file:///storage/emulated/0/Android/data/com.myappname.app/folder/subfolder/file.txt content://com.android.providers.downloads.documents/tree/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FSAFfolder/newname.txt

Я получаю

java.lang.IllegalArgumentException: Invalid URI: file:///storage/emulated/0/Android/data/com.myappname.app/folder/subfolder/file.txt

при

DocumentFile docFile=DocumentFile.fromTreeUri(activity,parentFolderUri).findFile(fileName);

во втором методе

или, когда Log.d () комментируется,

java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.ContentProviderClient.call(java.lang.String, java.lang.String, android.os.Bundle)' on a null object reference

в этой строке:

DocumentsContract.copyDocument(resolver,Uri.parse(docUri),Uri.parse(targetFolderUri));

в первом методе.Что не так с моим кодом?Разрешена ли авторизация личной папки?Как их авторизовать?

Ответы [ 2 ]

0 голосов
0 голосов
/ 28 сентября 2019

Что не так с моим кодом?

Ни docUri, ни parentFolderUri не является документом Uri.Это Uri значения, которые вы создали, используя Uri.fromFile() или что-то еще.Вы можете сказать, потому что у них есть схема file.

Что касается вашего немедленного сбоя, fromTreeUri() требует документ Uri.Используйте fromFile() для file Uri значений.

Как только вы пройдете через это, я ожидаю, что вы потерпите крах в вашем copyDocument() звонке.Это то, что я изначально думал, что проблема была, пока я не перечитал ваш вопрос.Вы пытаетесь скопировать не-документ Uri (docUri) и в JavaDocs для copyDocument() указано, что первым параметром должен быть документ Uri:

документ с Документом # FLAG_SUPPORTS_COPY Это значение никогда не должно быть нулевым.

Когда DocumentsContract обозначает Uri как «документ», это означает Uri, полученный через DocumentsContract сама.Это будет включать Uri, полученный с помощью ACTION_OPEN_DOCUMENT или Uri, полученный с помощью дерева DocumentFile.Однако это не распространяется на:

  • A Uri, созданный Uri.fromFile()
  • A Uri из FileProvider.getUriForFile()
  • A Uri созданUri.parse() с http или https URL
  • и т. д.

Разрешено ли использование Uris для личной папки?

Это не вопрос «авторизации».fromTreeUri() ожидает документ Uri.copyDocument() ожидает документ Uri.Вы не можете использовать их с недокументированными значениями Uri, вот и все.

...