为什么 ContentResolver.openFileDescriptor 会抛出 IllegalArgumentException?出路?

red*_*man 5 android android-contentresolver

我有两个问题,为了让我的问题在这里清晰,一个简短的代码片段:

ContentResolver resolver = context.getContentResolver();
DocumentsContract.deleteDocument(resolver, documentUri);
resolver.openFileDescriptor(documentUri, "rw");
Run Code Online (Sandbox Code Playgroud)

文档说最后一行“如果 URI 下不存在文件或模式无效,则抛出 FileNotFoundException”。

但实际上我得到java.lang.IllegalArgumentException.

(问题 1)这是一个错误还是可以?

(问题2)openFileDescriptor()显然不是测试文档是否存在的好方法。什么是“官方”方法来做到这一点?

编辑(添加错误日志):

W/System.err: java.lang.IllegalArgumentException: 无法确定 9016-4EF8:myFolder/file1.wav 是否是 9016-4EF8:myFolder: java.io.FileNotFoundException: Missing file for 9016-4EF8:myFolder/file1 .wav 在 /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"

Com*_*are 2

这是一个错误还是正常?

我认为这是一个错误,因为它应该FileNotFoundException在这里抛出一个错误。

openFileDescriptor() 显然不是测试文档是否存在的好方法。做到这一点的“官方”方法是什么?

简单的解决方案是使用DocumentFile及其exists()方法。

如果我能够毫无问题地删除 documentUri 标识的文档,那么实际文档的性质不应该与 openFileDescriptor 相关,不是吗?

嗯,这有助于知道应该责怪谁。在这种情况下,问题出在谷歌身上。

关于 DocumentFile:我成功地避免了它,并且想知道我现在是否仅仅因为存在()而被迫包含它?

如果您愿意,当然欢迎您克隆它的实现exists()。借助一些间接的方式,您可以在以下位置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);
    }
}
Run Code Online (Sandbox Code Playgroud)