web-dev-qa-db-fra.com

ne peut pas supprimer le fichier du stockage externe dans Android par programmation

J'essaie de supprimer un fichier situé sur le chemin

/storage/714D-160A/Xender/image/Screenshot_commando.png

Ce que j'ai fait jusqu'à présent:

  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();
     }

et le fichier est toujours à sa place (Non supprimé :()

J'ai également donné l'autorisation dans le fichier Manifest.

<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" />
14
Secret
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();
}
11
Secret

L'utilisation de ContentResolver pour supprimer des fichiers multimédias est incorrecte et pose de nombreux problèmes à l'utilisateur.
Vous ne pouvez pas supprimer un fichier du sd-card Simplement en supprimant ses informations des ContentResolver on Android supérieures à Jelly bean(4.3).
Il fonctionne uniquement sur les versions Android antérieures à KitKat(4.4).
C'est pourquoi l'équipe Android a fourni DocumentProvider .

Pourquoi contentResolver.delete(...) est faux?
1. Remplit le sd-card
Lorsque vous essayez de supprimer un fichier multimédia sur le sd-card Par le ContentResolver on Android versions supérieures à 4.3, le fichier multimédia réel restera intacte car l'approche contentResolver.delete(...) ne supprime que les informations (nom, date, chemin ...) des médias et vous finirez par avoir des fichiers multimédias non enregistrés sur votre sd-card qui ContentResolver n'a aucune idée de leur existence et c'est pourquoi vous ne pouviez pas les voir dans votre galerie et vous pensez qu'ils ont été supprimés avec cette approche alors qu'ils sont toujours là et remplissez le sd-card chaque fois que l'utilisateur essaie de supprimer un média fichier sur le sd-card.

2. Les fichiers multimédias (Images, vidéos, gifs ...) reviendront dans la galerie
Il existe de nombreuses applications, en particulier celles de la galerie et du gestionnaire de fichiers, qui trouveront ces fichiers multimédias non enregistrés et les ajouteront à nouveau à ContentResolver à partir de leur comportement normal pendant que l'utilisateur assume ses médias indésirables. les fichiers ont disparu. Bien sûr, aucun utilisateur ne veut que ses images ou vidéos supprimées apparaissent au milieu d'une démonstration.

Alors, quelle est la bonne approche pour supprimer les fichiers multimédias sur le sd-card?
Eh bien, cela a déjà été répondu ici avec l'utilisation de DocumentProvider.

11
Eftekhari

À partir de Android 4.4 et versions ultérieures, vous ne pouvez pas écrire sur les fichiers de la carte SD (sauf dans le répertoire App) en utilisant la manière normale. Vous devrez utiliser le Storage Access Framework en utilisant DocumentFile pour ça.

Le code suivant fonctionne pour moi:

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 est le nom du fichier à supprimer et uri est l'URI retourné par 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 */
            }
        }
    }
}
4
Spikatrix

Utilisez Environment.getExternalStorageDirectory().getAbsolutePath() au lieu du chemin de stockage de codage en dur

String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File f = new File(baseDir + "/714D-160A/Xender/image/Screenshot_commando.png");
boolean d = f.delete();
3
SiSa