не может удалять файл из внешнего хранилища в программном обеспечении Android
Я пытаюсь удалить файл, расположенный по пути
/storage/714D-160A/Xender/image/Screenshot_commando.png
Что я сделал до сих пор:
try{
String d_path = "/storage/714D-160A/Xender/image/Screenshot_commando.png";
File file = new File(d_path);
file.delete();
}catch(Exception e){
e.printStackTrace();
}
и файл все еще находится на своем месте (не удаляется :()
Также я дал разрешение в файле манифеста.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.STORAGE" />
Ответы
Ответ 1
public static boolean delete(final Context context, final File file) {
final String where = MediaStore.MediaColumns.DATA + "=?";
final String[] selectionArgs = new String[] {
file.getAbsolutePath()
};
final ContentResolver contentResolver = context.getContentResolver();
final Uri filesUri = MediaStore.Files.getContentUri("external");
contentResolver.delete(filesUri, where, selectionArgs);
if (file.exists()) {
contentResolver.delete(filesUri, where, selectionArgs);
}
return !file.exists();
}
Ответ 2
Использование ContentResolver
для удаления мультимедийных файлов является неправильным и создает много проблем для пользователя.
Вы не можете удалить файл на sd-card
просто удалив его информацию из ContentResolver
на версиях Android, превышающих Jelly Bean(4.3)
.
Работает только на версиях Android до KitKat(4.4)
.
Именно поэтому команда Android предоставила DocumentProvider.
Почему contentResolver.delete(...)
не так?
1. Заполняет sd-card
Когда вы пытаетесь удалить медиа файл на sd-card
с помощью ContentResolver
на версиях Android выше 4.3, фактический медиа файл останется нетронутым, поскольку contentResolver.delete(...)
удаляет только информацию (имя, дату, путь...) мультимедиа, и в итоге вы получите незарегистрированные мультимедийные файлы на своей sd-card
которые ContentResolver
больше не знает об их существовании, и поэтому вы не могли видеть их в своей галерее, и вы думаете, что они были удаляется с помощью этого подхода, пока они еще там, и заполняет sd-card
каждый раз, когда пользователь пытается удалить медиа файл с sd-card
.
2. Медиа файлы (изображения, видео, GIF файлы...) вернутся в галерею
Существует множество приложений, особенно галерей и файловых менеджеров, которые найдут эти незарегистрированные мультимедийные файлы и снова добавят их в ContentResolver
в обычном режиме, в то время как пользователь считает, что его/ее ненужные мультимедийные файлы пропали. Конечно, ни один пользователь не хочет, чтобы его/ее предположили, что удаленные изображения или видео появляются в середине демонстрации.
Итак, какой правильный подход к удалению медиафайлов на sd-card
?
Ну, это уже отвечал здесь с использованием DocumentProvider
.
Ответ 3
Используйте Environment.getExternalStorageDirectory().getAbsolutePath()
вместо жесткого пути хранения данных
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File f = new File(baseDir + "/714D-160A/Xender/image/Screenshot_commando.png");
boolean d = f.delete();
Ответ 4
Начиная с Android 4.4, вы не можете записывать в файлы SD-карты (кроме каталога App) обычным способом. Для этого вам придется использовать Storage Access Framework, используя DocumentFile
.
Следующий код работает для меня:
private void deletefile(Uri uri, String filename) {
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri);
try {
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (SecurityException e) {
e.printStackTrace();
}
DocumentFile file = pickedDir.findFile(filename);
if(file.delete())
Log.d("Log ID", "Delete successful");
else
Log.d("Log ID", "Delete unsuccessful");
}
где filename
- это имя файла, который нужно удалить, а uri
- это URI, возвращаемый ACTION_OPEN_DOCUMENT_TREE
:
private static final int LOCATION_REQUEST = 1;
private void choosePath() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, LOCATION_REQUEST);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (requestCode == LOCATION_REQUEST && resultCode == Activity.RESULT_OK) {
Uri uri;
if (resultData != null) {
uri = resultData.getData();
if (uri != null) {
try {
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (SecurityException e) {
e.printStackTrace();
}
/* Got the path uri */
}
}
}
}