Android通过 uri 删除文件
通过 “file://” 开头的 uri 删除文件
如果是以 “file://” 开头的 uri,删除文件的方式比较简单(需要加上 WRITE_EXTERNAL_STORAGE 权限):
new File(fileUri.getPath()).delete();
通过 “content://” 开头的 uri 删除文件
通过 ContentResolver.delete 删除文件
但是如果是以 “content://” 开头的 uri,就比较麻烦了。在网上找到的很多方法,都是通过这种方式实现:
context.getContentResolver().delete(getIntent().getData(), null, null);
但是实测发现 ContentResolver 在这里的实现类是 DocumentsProvider,而它的 delete 方法是不支持的,会抛出异常。
@Override
public final int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("Delete not supported");
}
通过 DocumentFile.fromSingleUri 删除文件
如果你的应用能导入 android-support-v4 包,可以通过以下代码实现:
import android.support.v4.provider.DocumentFile;
DocumentFile.fromSingleUri(context.getApplicationContext(),fileUri).delete();
通过 DocumentsContract.deleteDocument 删除文件
由于修改的是系统应用,非必要不想导入多余的包,于是看了一下 DocumentFile.fromSingleUri
的接口实现,发现最终调用的还是 android 原生的方法。于是可以改为通过以下代码实现:
import android.provider.DocumentsContract;
DocumentsContract.deleteDocument(context.getContentResolver(), fileUri);
通过以上方式删除文件,可能会有权限问题,我是直接简单粗暴加上了管理文件的权限:
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
通过 uri 获取文件绝对路径后删除文件
上述方式毕竟还是放大了应用的权限,还是不那么妥当。于是我尝试寻找通过 uri 获取文件路径的方式,参考了别人的博客,通过以下方式也可以实现删除文件:
if(ContentResolver.SCHEME_CONTENT.equals(originUri.getScheme())) {
String authority = originUri.getAuthority();
if(authority.startsWith("com.android.externalstorage")) {
String originPath = Environment.getExternalStorageDirectory() + "/" + originUri.getPath().split(":")[1];
new File(originPath).delete();
}
}
当然,这种方式需要针对不同的路径进行处理。这里也只是做了尝试,多一种解决问题的思路。
参考文章
Android: delete file trought a content uri
【Android 11/12】 通过Uri获取绝对路径的方法