SAF-将文件从私有应用文件夹复制到授权的SAF文件夹时出现无效的Uri错误

时间:2019-09-28 10:39:54

标签: android directory nullpointerexception file-copying storage-access-framework

我的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));

在第一种方法中。 我的代码有什么问题?私人文件夹uris是否未被授权?如何授权他们?

2 个答案:

答案 0 :(得分:0)

  

我的代码怎么了?

docUriparentFolderUri都不是文档Uri。它们是您使用Uri或其他内容创建的Uri.fromFile()值。您可以知道,因为他们有file方案。

关于您的当机崩溃,fromTreeUri()需要文档Uri。将fromFile()用作file Uri的值。

一旦您超过了该限制,我希望您会在copyDocument()通话中崩溃。这就是我最初认为的问题所在,直到我重新阅读您的问题。您正在尝试复制非文档UridocUri),并且the JavaDocs for copyDocument()指出第一个参数必须是文档Uri

  

带有Document#FLAG_SUPPORTS_COPY的文档。此值绝不能为空。

DocumentsContractUri称为“文档”时,表示通过Uri本身获得的DocumentsContract。其中包括通过Uri获得的ACTION_OPEN_DOCUMENT或通过树Uri获得的DocumentFile。但是,这将不包括:

  • Uri创建的Uri.fromFile()
  • 来自Uri的{​​{1}}
  • FileProvider.getUriForFile()通过UriUri.parse() URL创建的http
  • 等等。
  

未授权私人文件夹uris?

这不是“授权”的问题。 https需要一个文档fromTreeUri()Uri需要一个文档copyDocument()。您不能将它们与非文档的Uri值一起使用。

答案 1 :(得分:0)