如何在Android Q中使用DocumentFile删除文件?

huangapple go评论72阅读模式
英文:

How to delete files with DocumentFile in Android Q?

问题

删除带有文档 URI 的文件的方法

private void getDocumentUri(Uri mediaUri){
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && getActivity() != null) {
            Uri documentUri = MediaStore.getDocumentUri(getActivity(), mediaUri);
            if (documentUri != null) {
                Log.d(TAG, "getDocumentUri: " + documentUri);
                DocumentFile documentFile = DocumentFile.fromSingleUri(getActivity(), documentUri);
                if (documentFile != null) {
                    Log.d(TAG, "getDocumentUri 文档文件不为空: " + documentFile);
                    if (documentFile.delete()) {
                        Log.i(TAG, "getDocumentUri 删除成功");
                    } else {
                        Log.i(TAG, "getDocumentUri 删除失败");
                    }
                }
            }
        }
    } catch (Exception e) {
        Log.e(TAG, "getDocumentUri 错误: " + e);
    }
}

Logcat 错误

SecurityException: 该应用未被授予访问路径为 /storage/emulated/0/test/song.mp3 的文档的权限,权限授予于 [UriPermission {uri=content://com.android.externalstorage.documents/tree/primary%3AMusic, modeFlags=3, persistedTime=1601203263354}]

奇怪的是,对于某些文件,这个方法可以正常工作,而对于某些文件,会出现上述错误,所有音频文件都位于内部存储的同一位置。

编辑

mediaUri 的值是通过以下方式获得的:ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));

此外,我尝试删除的文件并不是由我的应用程序创建的。

英文:

Method for deleting file with document uri

private void getDocumentUri(Uri mediaUri){
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && getActivity() != null) {
                Uri documentUri = MediaStore.getDocumentUri(getActivity(), mediaUri);
                if (documentUri != null) {
                    Log.d(TAG,"getDocumentUri: "+documentUri);
                    DocumentFile documentFile = DocumentFile.fromSingleUri(getActivity(), documentUri);
                    if (documentFile != null) {
                        Log.d(TAG, "getDocumentUri documentFile not null: " + documentFile);
                        if (documentFile.delete()) {
                            Log.i(TAG, "getDocumentUri Delete successful");
                        } else {
                            Log.i(TAG, "getDocumentUri Delete unsuccessful");
                        }
                    }
                }
            }
        }catch(Exception e){
            Log.e(TAG,"getDocumentUri error: " + e);
        }
}

Logcat error

SecurityException: The app is not given any access to the document under path /storage/emulated/0/test/song.mp3 with permissions granted in [UriPermission {uri=content://com.android.externalstorage.documents/tree/primary%3AMusic, modeFlags=3, persistedTime=1601203263354}]

Weird thing is that for some files this works and for some it gives this error and all audio files are in the same place on the internal storage.

EDIT

mediaUri's value is obtained with ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));

Also the files i'm trying to delete are not created by my app

答案1

得分: 1

试试这个方法。您需要使用SAF获取父文件夹的可持续性URI权限,然后将要删除的文件的URI和名称传递进去。(我有一个模型类来处理这两者。)

public void deleteAPI29(ArrayList<Media> mediaList) {
    Uri persistedUri = getContentResolver().getPersistedUriPermissions().get(0).getUri();
    DocumentFile documentFile = DocumentFile.fromTreeUri(this, persistedUri);
    for (int i = 0; i < mediaList.size(); i++) {
        File file = new File(mediaList.get(i).getPath());
        DocumentFile nextDocument = documentFile.findFile(file.getName());
        try {
            DocumentsContract.deleteDocument(getContentResolver(), nextDocument.getUri());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
英文:

Try this method. You need to take the persistable uri permission using SAF of the parent folder, then pass the uri & name of the file to delete. (I have a model class to handle both.)

public void deleteAPI29(ArrayList&lt;Media&gt; mediaList) {
        Uri persistedUri = getContentResolver().getPersistedUriPermissions().get(0).getUri();
        DocumentFile documentFile = DocumentFile.fromTreeUri(this, persistedUri);
        for (int i = 0; i &lt; mediaList.size(); i++) {
            File file = new File(mediaList.get(i).getPath());
            DocumentFile nextDocument = documentFile.findFile(file.getName());
            try {
                DocumentsContract.deleteDocument(getContentResolver(), nextDocument.getUri());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

huangapple
  • 本文由 发表于 2020年9月27日 18:45:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/64087565.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定