我一直在阅读 android 文档,但找不到 的解决方案在没有多个对话框的情况下删除多个文件 在 Android 10(API 级别 29)中
我在 Android 文档中找到了以下内容:
这不仅对我而且对每个 API 级别 29 的用户都非常令人沮丧,因为在某些用例中必须删除多达 100 多个文件。
想要删除媒体时的入口点
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
deleteMediaR(activity, uris)
}
Build.VERSION.SDK_INT == Build.VERSION_CODES.Q -> {
deleteMediaQ(activity, uris)
}
else -> {
deleteMediaDefault(activity, uris)
}
API 级别 29 以上 @RequiresApi(Build.VERSION_CODES.R)
private fun deleteMediaR(activity: Activity, uris: ArrayList<String>) {
val contentResolver = activity.contentResolver
val collection: ArrayList<Uri> = ArrayList()
collection.addAll(uris.map { uri -> Uri.parse(uri) })
val pendingIntent = MediaStore.createDeleteRequest(contentResolver, collection)
activity.startIntentSenderForResult(
pendingIntent.intentSender, 42, null, 0, 0, 0, null)
}
API 级别 29 @RequiresApi(Build.VERSION_CODES.Q)
private fun deleteMediaQ(activity: Activity, uris: ArrayList<String>) {
try {
deleteMediaDefault(activity, uris)
} catch (exception: Exception) {
if (exception is RecoverableSecurityException) {
val pendingIntent: PendingIntent = exception.userAction.actionIntent
activity.startIntentSenderForResult(pendingIntent.intentSender,
42, null, 0, 0, 0, null)
}
}
}
API 级别 29 以下 contentResolver.delete(uri, where, media))
这是一个非常令人沮丧的问题,仅涉及 Android 10。我假设 Google 忘记在他们的 API 中实现此功能。但是,我希望有一个适当的解决方案,因为这会在使用 Android 10 时破坏应用程序。
最佳答案
实际上,您可以通过两种方式进行操作。
1. 使用媒体存储:
您可以像这样使用 Mediastore 删除 API 轻松删除任何媒体文件,
ActivityResultLauncher<IntentSenderRequest> deleteLauncher
= registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == RESULT_OK) {
// Media files deleted successfully. Do your stuff.
}
}
});
@RequiresApi(api = Build.VERSION_CODES.R)
private void deleteAPI30(ArrayList<Media> mediaList, Context context) throws IntentSender.SendIntentException {
ContentResolver contentResolver = context.getContentResolver();
List<Uri> uriList = new ArrayList<>();
for (int i = 0; i < mediaList.size(); i++) {
uriList.add(mediaList.get(i).getAppendedIdUri());
}
Collections.addAll(uriList);
PendingIntent pendingIntent = MediaStore.createDeleteRequest(contentResolver, uriList);
IntentSenderRequest senderRequest = new IntentSenderRequest.Builder(pendingIntent.getIntentSender())
.setFillInIntent(null)
.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 0)
.build();
deleteLauncher.launch(senderRequest);
}
附言如果事情不顺利,您需要使用 SAF 目录选择器获得目录访问权限。2. 使用存储访问框架 (SAF) 删除:
public void deleteMediaSAF(ArrayList<Media> mediaList) {
DocumentFile documentFile = DocumentFile.fromTreeUri(this, getContentResolver().getPersistedUriPermissions().get(0).getUri());
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();
}
}
mediaList = loadMedia(DIR_NAME);
adapter.setMediaList(mediaList);
adapter.notifyDataSetChanged();
adapter.deselectAll();
if (mediaList.size() > 0) {
hideEmptyView();
} else {
showEmptyView();
menuItem.setVisible(false);
}
}
如果可能,您可以同时将这些方法用于不同的 API。例如,使用适用于 Android 11 及更高版本的 Mediastore API 和适用于 Android 10 的 SAF API。
关于Android 10 无法删除多个文件(范围存储),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70318511/