не может удалять файл из внешнего хранилища в программном обеспечении 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 */
            }
        }
    }
}