为什么 ContentResolver.openFileDescriptor 抛出 IllegalArgumentException?出路?
Why ContentResolver.openFileDescriptor throws IllegalArgumentException? Way out?
我有两个问题,这里用一段简短的代码来说明我的问题:
ContentResolver resolver = context.getContentResolver();
DocumentsContract.deleteDocument(resolver, documentUri);
resolver.openFileDescriptor(documentUri, "rw");
文档说最后一行 "Throws FileNotFoundException if no file exists under the URI or the mode is invalid."
但实际上我得到了java.lang.IllegalArgumentException
。
(问题 1)这是错误还是正常?
(问题2) openFileDescriptor()
显然不是一个测试文档是否存在的好方法。 "official" 的方法是什么?
编辑(添加错误日志):
W/System.err: java.lang.IllegalArgumentException: 无法确定 9016-4EF8:myFolder/file1.wav 是否为 9016-4EF8:myFolder 的 child: java.io.FileNotFoundException:9016-4EF8 缺少文件:myFolder/file1.wav at /storage/extSdCard/myFolder/file1.wav
W/System.err: 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
W/System.err: 在 android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:148)
W/System.err: 在 android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:618)
W/System.err: 在 android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:945)
W/System.err: 在 android.content.ContentResolver.openFileDescriptor(ContentResolver.java:784)
W/System.err: 在 android.content.ContentResolver.openFileDescriptor(ContentResolver.java:739)
和:
documentUri="content://com.android.externalstorage.documents/tree/9016-4EF8%3AmyFolder/document/9016-4EF8%3AmyFolder%2Ffile1.wav"
Is this a bug or OK?
我认为这是一个错误,因为它应该在这里抛出 FileNotFoundException
。
openFileDescriptor() is obviously not a good method to test if the document exists. What is the "official" method to do that?
简单的解决方案是使用 DocumentFile
及其 exists()
方法。
If I'm able to remove the document identified by documentUri without any problem then the nature of the actual document shouldn't be relevant for openFileDescriptor, should it?
好吧,知道应该责怪谁是有帮助的。在这种情况下,问题出在 Google.
And concerning DocumentFile: I successfully avoided it and wonder if I'm now forced to include it only because of exists()?
如果您愿意,当然欢迎您克隆其 exists()
的实现。由于一些间接的原因,你会发现它 in DocumentsContractApi19
:
public static boolean exists(Context context, Uri self) {
final ContentResolver resolver = context.getContentResolver();
Cursor c = null;
try {
c = resolver.query(self, new String[] {
DocumentsContract.Document.COLUMN_DOCUMENT_ID }, null, null, null);
return c.getCount() > 0;
} catch (Exception e) {
Log.w(TAG, "Failed query: " + e);
return false;
} finally {
closeQuietly(c);
}
}
我有两个问题,这里用一段简短的代码来说明我的问题:
ContentResolver resolver = context.getContentResolver();
DocumentsContract.deleteDocument(resolver, documentUri);
resolver.openFileDescriptor(documentUri, "rw");
文档说最后一行 "Throws FileNotFoundException if no file exists under the URI or the mode is invalid."
但实际上我得到了java.lang.IllegalArgumentException
。
(问题 1)这是错误还是正常?
(问题2) openFileDescriptor()
显然不是一个测试文档是否存在的好方法。 "official" 的方法是什么?
编辑(添加错误日志):
W/System.err: java.lang.IllegalArgumentException: 无法确定 9016-4EF8:myFolder/file1.wav 是否为 9016-4EF8:myFolder 的 child: java.io.FileNotFoundException:9016-4EF8 缺少文件:myFolder/file1.wav at /storage/extSdCard/myFolder/file1.wav
W/System.err: 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
W/System.err: 在 android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:148)
W/System.err: 在 android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:618)
W/System.err: 在 android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:945)
W/System.err: 在 android.content.ContentResolver.openFileDescriptor(ContentResolver.java:784)
W/System.err: 在 android.content.ContentResolver.openFileDescriptor(ContentResolver.java:739)
和:
documentUri="content://com.android.externalstorage.documents/tree/9016-4EF8%3AmyFolder/document/9016-4EF8%3AmyFolder%2Ffile1.wav"
Is this a bug or OK?
我认为这是一个错误,因为它应该在这里抛出 FileNotFoundException
。
openFileDescriptor() is obviously not a good method to test if the document exists. What is the "official" method to do that?
简单的解决方案是使用 DocumentFile
及其 exists()
方法。
If I'm able to remove the document identified by documentUri without any problem then the nature of the actual document shouldn't be relevant for openFileDescriptor, should it?
好吧,知道应该责怪谁是有帮助的。在这种情况下,问题出在 Google.
And concerning DocumentFile: I successfully avoided it and wonder if I'm now forced to include it only because of exists()?
如果您愿意,当然欢迎您克隆其 exists()
的实现。由于一些间接的原因,你会发现它 in DocumentsContractApi19
:
public static boolean exists(Context context, Uri self) {
final ContentResolver resolver = context.getContentResolver();
Cursor c = null;
try {
c = resolver.query(self, new String[] {
DocumentsContract.Document.COLUMN_DOCUMENT_ID }, null, null, null);
return c.getCount() > 0;
} catch (Exception e) {
Log.w(TAG, "Failed query: " + e);
return false;
} finally {
closeQuietly(c);
}
}