当前位置: 首页 > 面试题库 >

存储访问框架-无法从uri获取文档树(从云端硬盘应用返回)

柳俊逸
2023-03-14
问题内容

我的Android应用程序想要在Google云端硬盘中创建一个文件夹,并从设备上的云端硬盘应用程序获取uri。

它发送一个意图,您可以看到以下代码:

private void createFolder(String folderName) {
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Create a file with the requested MIME type.
    intent.setType("vnd.android.document/directory");
    intent.putExtra(Intent.EXTRA_TITLE, folderName);
    startActivityForResult(intent, WRITE_REQUEST_CODE);
}

然后获取返回的数据,您可以看到以下代码:

@Override
protected void  onActivityResult(int requestCode, int resultCode, Intent resultData)
{

    if (requestCode == WRITE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {

        Uri uri = null;
       if (resultData != null) {
            uri = resultData.getData();
            Log.i("result", "Uri: " + uri.toString());
            DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri); //this line gives the error
                       }
    }

}

我使用了在互联网上发现的一种模仿类型,它似乎是一种标准类型。使用“ application / vnd.google-
apps.folder”时会发出相同的错误。目标是要有一个文档树,但是在logcat中,我得到以下错误:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=43, result=-1, data=Intent { dat=content://com.google.android.apps.docs.storage/document/acc=1;doc=encoded=LongStringWithRandomCharactersHere/j flg=0x43 }} to activity {com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.IllegalArgumentException: Invalid URI: content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3Dencoded%3DSameLongStringWithRandomCharactersHere%2Fj

及以下

Caused by: java.lang.IllegalArgumentException: Invalid URI: content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3Dencoded%3DAnotherLongStringWithDifferentRandomDataHere

这是完整的堆栈跟踪:

2019-05-31 15:06:50.167 31184-31184/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 31184
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=43, result=-1, data=Intent { dat=content://com.google.android.apps.docs.storage/document/acc=1;doc=encoded=randomcharacters flg=0x43 }} to activity {com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.IllegalArgumentException: Invalid URI: content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3Dencoded%3Drandomcharacters
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4365)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4409)
    at android.app.ActivityThread.-wrap19(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1670)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6687)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
 Caused by: java.lang.IllegalArgumentException: Invalid URI: content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3Dencoded%3Drandomcharacters
    at android.provider.DocumentsContract.getTreeDocumentId(DocumentsContract.java:1023)
    at android.support.v4.provider.DocumentFile.fromTreeUri(DocumentFile.java:138)
    at com.example.myapplication.MainActivity.onActivityResult(MainActivity.java:254)
    at android.app.Activity.dispatchActivityResult(Activity.java:7295)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4361)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4409) 
    at android.app.ActivityThread.-wrap19(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1670) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6687) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)

uri没错,因为我可以进一步提取在云端硬盘上成功创建的文件夹的名称(大小为= 0)。怎么了?看来我的应用无法将其作为文档树来处理。


问题答案:

这可以与Google云端硬盘的云空间配合使用,但也许是黑客。不能保证始终工作。

示例在用户创建的云文件夹中创建一个云文件(SAF选择器由应用程序打开)。

创建云文件夹(用户必须首先从选择器UI中选择云根)

 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);
 startActivityForResult(intent, CREATE_DIRECTORY_REQUEST_CODE);

onActivityResult

@Override
protected void onActivityResult(int requestCode,int resultCode, Intent data) 
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CREATE_DIRECTORY_REQUEST_CODE) 
    {
      if (resultCode == Activity.RESULT_OK) {
      int takeFlags = data.getFlags()
                   &
      (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
      ContentResolver resolver = this.getContentResolver();
      resolver.takePersistableUriPermission(data.getData(),takeFlags);
      archiveUri(data.getData().toString()); //important to save the toString() result, not getPath()
      archiveAuthority(data.getData().getAuthority());
      } 
      else 
      {
            // The user cancelled the request.
      }
    }
}

下次使用Uri

ContentResolver contentResolver;
contentResolver = this.getContentResolver();
uriPath=retrieveArchivedUri();
Uri tempUri;
Uri uri; 
String authority;
tempUri=Uri.parse(uriPath);
authority=retrieveArchivedAuthority();
uri= DocumentsContract.buildDocumentUri(authority,
            DocumentsContract.getDocumentId(tempUri)); //folder Uri

try 
{
 DocumentsContract.createDocument(contentResolver,uri,"plain/text","fileName");
} 
catch (FileNotFoundException e) 
{
        e.printStackTrace();
}


 类似资料:
  • 在Android4.4(KitKat)的新图库访问之前,我通过以下方法在SD卡上获得了我的真实路径: 现在,intent.action_get_content返回不同的数据: 我怎样才能获得SD卡上的真实路径?

  • 让我分享到目前为止我所学到的,并提出我的问题。如果希望获取文件夹的Uri并对其进行操作,则应使用和获取访问文件夹的Uri,并为该Uri设置W/R权限。 授予onActivityResult的持久权限: 如果选择设备的主文件夹: 如果使用DocumentFile类获取主文件夹的路径 返回:file:///storage/emulated/0 我的第一个问题是如何使用DocumentFile类获得包含

  • 从Google云应用程序中,我需要打开位于项目云存储中的文件。我试图使用以下表单的URL访问该文件,但出现以下错误:http://storage.googleapis.com/my-bucket/my-file错误:访问被拒绝。匿名调用方没有存储对象 www.googleapis。com/上传/存储/v1/b/http://my_appl//my-bucket/my-file错误404 www.g

  • 我正在构建一个android应用程序,使用谷歌app engine后端。 我在谷歌云存储的一个桶里有一些音频文件(手动上传),我想从后端访问它们(我想获得它们的URL并将它们发送到我的应用程序,这样它就可以播放音频文件)。 谢谢:)

  • 我想从接收正常文件路径,如下所示: 这个文件也存在,但我不能得到它。我在这里看到了一些建议获得路径的问题,如下所示: 但此方法返回以下异常: 因此,我在这里收到的: 如何将文件转换为字符串: