Android's Media Scanner: How do I remove files

2019-01-17 09:18发布

问题:

I'm writing an app that removes files that may or may not be listed in any one of the types of media libraries such as music or pictures. While I can use the MediaScannerConnection.scanFile method to add files to the media library there doesn't seem to be any call to notify the service that the file has been removed. Sending it the path of the file that no longer exists doesn't result in the desired behavior either. How should I go about removing items from the library that no longer exist on the Android storage?

回答1:

The following works well for me. You can delete or add files using this.

MediaScannerConnection.scanFile(
                context,
                new String[]{fileToDelete, fileToAdd},
                null, null);


回答2:

I was able to put a method together using bits and pieces from these two questions

  1. What is the String 'volumeName' argument of MediaStore.Audio.Playlists.Members.getContentUri referring to?
  2. How can I refresh MediaStore on Android?

Basically I just run a query on each one of the MediaStore types (Audio, Video and Images) selecting by path and deleting any records I find.

public static void RemoveAllForPaths(String[] paths, Context context)
{
    private static final String[] FIELDS = { MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.TITLE };
    if(paths == null || paths.length == 0) return;
    String select = "";
    for(String path : paths)
    {
        if(!select.equals("")) select += " OR ";
        select += MediaStore.MediaColumns.DATA + "=?";
    }

    Uri uri;
    Cursor ca;

    uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    ca = context.getContentResolver().query(uri, FIELDS, select, paths, null);
    for(ca.moveToFirst(); !ca.isAfterLast(); ca.moveToNext()){
        int id = ca.getInt(ca.getColumnIndex(MediaStore.MediaColumns._ID));
        uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
        context.getContentResolver().delete(uri, null, null);
    }
    ca.close();

    // More of the same just setting the URI to Video and Images
}

I'm not entirely sure how safe this is to do but it's the only solution I've found so far and some initial testing seems to be working. I invite others to submit other answers if anyone has any further information on this approach or a better method for performing this functionality.



回答3:

Answer of Spencer Ruport is right, but you don't need to query and open a cursor in order to delete. So for one file that is music file the code is simple like that:

public void DeleteMP3FromMediaStore( Context context, String path )
{
    Uri rootUri = MediaStore.Audio.Media.getContentUriForPath( path );

    context.getContentResolver().delete( rootUri, 
        MediaStore.MediaColumns.DATA + "=?", new String[]{ path } );
}

P.S. I wanted to comment answer of Spencer Ruport but don't have enough reputation yet.



回答4:

Easy as pie: whenever you add a file, let MediaStore Content Provider knows about it using

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(fileToAddInMediaStore)));

For deletion: just use getContentResolver().delete(Uri.fromFile(fileToDeleteFromMediaStore), null, null)



回答5:

The available method is to remove the item from library. This post is detailed expressed how to add into or remove from the Media Library. http://androidyue.github.io/blog/2014/01/19/scan-media-files-in-android/ Hopes this could help you.