java – 存储访问框架 – 无法从uri获取文档树(从Drive应用程序返回)
作者:互联网
我的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
}
}
}
我使用了互联网上发现的mimetype,它似乎是一种标准类型.使用“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();
}
标签:directory-structure,android,java,uri,storage-access-framework 来源: https://codeday.me/bug/20190928/1826206.html