正确删除 DocumentFile(尊重 MediaStore)

Posted

技术标签:

【中文标题】正确删除 DocumentFile(尊重 MediaStore)【英文标题】:Correctly delete DocumentFile (respecting the MediaStore) 【发布时间】:2016-06-20 07:37:10 【问题描述】:

我有一个DocumentFile,通过以下两种方式定义:

DocumentFile documentFile;
Uri documentFileUri;

我可以通过以下方法从sd卡中删除一个文档文件:

    documentFile.delete(); DocumentsContract.deleteDocument(contentResolver, documentFileUri);

但以上方法均不会删除MediaStore中对应的条目。

处理这个问题的正确方法是什么?如果我使用ContentProvider 删除本地文件,它将从数据库中删除File 和行(contentResolver.delete(localFileUri, null, null);)。如果我使用DocumentsContract,我希望会发生同样的情况,但它不会发生......

我想要什么

我想立即更新MediaStore。通常我会打电话给contentResolver.delete(documentFileUri, null, null);,但这会失败,但会出现一个异常,即 uri 不支持删除...

问题

有没有比我的解决方法更有效的方法?

解决方法

目前我使用以下功能在删除DocumentFile后立即更新媒体存储:

public static boolean updateAfterChangeBlocking(String path, int timeToWaitToRecheckMediaScanner)

    final AtomicBoolean changed = new AtomicBoolean(false);
    MediaScannerConnection.scanFile(StorageManager.get().getContext(),
            new String[]path, null,
            new MediaScannerConnection.OnScanCompletedListener() 
                public void onScanCompleted(String path, Uri uri) 
                    changed.set(true);
                
            );

    while (!changed.get()) 
        try 
            Thread.sleep(timeToWaitToRecheckMediaScanner);
         catch (InterruptedException e) 
            return false;
        
    

    return true;

【问题讨论】:

为什么要使用 DocumentFile 来处理 MediaStore 中的内容?它们似乎不是相关的概念。如果您想使用 MediaStore,请仅使用其 API 中定义的对象和函数。此外,轮询循环不好。 :-( 因为即使在 android 6 上 Android 也会索引 sd 卡,这将导致媒体存储中 sd 卡中的文件...所以我必须考虑这一点,我必须混合 MediaStoreDocumentFile 并在更改 sd 卡上的文件时保持同步......当然循环很糟糕(这就是我称之为解决方法的原因),我想直接更新媒体存储,而不是我可以在很多本地文件的方法,但我在 sd 卡上找不到DocumentFile... 但是 DocumentFile 为您提供了 MediaStore 没有提供的什么?为什么不直接使用 MediaStore API 来处理所有事情? 因为你没有在sd卡上写的权限。您需要在 android 6 上使用 Storage Access Framework 来获得对 sd 卡的写访问权限,因此您需要在那里使用 DocumentFile... 使用路径和 File 类将无法工作,因为缺少权限.. . android 6 上没有其他方法了... @prom85 issuetracker.google.com/issues/138887165 这是我从谷歌得到的 【参考方案1】:

正如 fatboy 指出的那样,这种行为是设计使然 - 记录在这个谷歌问题中:https://issuetracker.google.com/issues/138887165

解决方案:

可能没有比我已经在我的问题中发布的更好的解决方案了:

通过DocumentFile对象或URIDocumentsContract.deleteDocument删除文件 对于即时媒体存储更新(这就是我想要的),您必须手动更新媒体存储,例如通过调用MediaScannerConnection.scanFile(...) 就像我已经在我的问题中发布了它

【讨论】:

谢谢!我也在努力实现类似的目标。顺便说一句,您是如何从 documentFile 中获取本地绝对路径的?

以上是关于正确删除 DocumentFile(尊重 MediaStore)的主要内容,如果未能解决你的问题,请参考以下文章

SAF DocumentFile - 检查路径是不是存在而不在每个文件夹级别创建每个 DocumentFile

是否可以从 DocumentFile 获取常规文件?

存储访问框架 - 设置本地 DocumentFile 的最后修改日期

如何在 C# 中正确捕获用户的击键,即尊重 SHIFT 键等

何时尊重 preferredContentSize?

输入为啥不尊重flex?