6

问题:如何使媒体存储刷新其已删除文件的条目?

从外部存储中删除代码中的照片后,我仍然在图库中看到已删除照片的插槽 - 空白照片。

画廊似乎反映了媒体商店,并且在媒体商店中找到了已删除的照片,直到手机重新启动或通常 - 直到重新扫描媒体。

尝试扫描已删除的文件无助于扫描已删除的文件(仅适用于新文件或现有文件):(MediaScannerConnection.scanFile(Application.get(), new String[]{file.getPath()}, null, null)我也尝试扫描父文件夹)。

也试过ACTION_MEDIA_SCANNER_SCAN_FILE无济于事。例子:Application.get().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)))

发送广播接收器以重新扫描整个外部存储(从而刷新媒体存储)就可以了:Application.get().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(Environment.getExternalStorageDirectory())))

但是,从4.4开始, Android 似乎在尝试手动发送 ACTION_MEDIA_MOUNTED 系统广播时引发了安全异常。请参阅@CommonsWare 的帖子:http ://commonsware.com/blog/2013/11/06/android-4p4-permission-regressions.html

因此,我无法在文件(/照片/视频/等)删除时刷新媒体存储的解决方案。

4

4 回答 4

3

我发现以下内容适用于 Nexus 10 上的 4.4。

// request scan
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, SELECT_PICTURE);
Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scanIntent.setData(Uri.fromFile(refreshFile));
sendBroadcast(scanIntent);

“refreshFile”是我从字符串“fPath”中删除的文件,然后将其转换为文件。

String filePath = fPath;        
File refreshFile = new File(filePath);
于 2013-11-23T15:15:58.337 回答
1

我遇到过同样的问题。我编写了以下代码,它适用于从棒棒糖到奥利奥的所有版本。我还调用了 mediastore.scanfile() 方法来确保 MediaStore 已更新。添加下面的代码 - 您将来可能不想使用“delete()”方法,因为 scanfile() 可能是全面的。但是,如果您想支持旧手机,那么 delete() 可能会更安全。

    // fileID == MediaStore.Images.Media._ID; for the file when you get the file from the content 
// resolver
public static boolean deleteCREntryForFilePath(Context context, String filePath, long fileID) {
    boolean         fDeleted       = false;
    ContentResolver cr             = context.getContentResolver();
    int             rowsDeleted    = 0;
    Uri             imageURI       = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    String          deleteStr      = MediaStore.Images.Media._ID + "=" + fileID;

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

    // Remove entry from database
    rowsDeleted = context.getContentResolver().delete(
            imageURI, deleteStr, null);
    if (rowsDeleted > 0)
        fDeleted = true;
    return(fDeleted);
}

这是获取文件 ID 的代码(函数名称是 getfileId())。它适用于不同的文件类型。您无法按原样编译代码,因为它使用内部对象类型,但您应该可以轻松地将其转换为通用用途。

public static String[] getCombinedEntityColumns(Constants.DELASHARE_OBJECT_TYPES objType) {
    String[] entityColumns = new String[5];

    switch (objType) {
        case DELASHARE_OBJECT_PICTURE:
        case DELASHARE_OBJECT_MUSIC:
        case DELASHARE_OBJECT_VIDEO: {

            entityColumns[0] = MediaStore.Images.Media.DISPLAY_NAME;
            entityColumns[1] = MediaStore.Images.Media.DATA;
            entityColumns[2] = MediaStore.Images.Media._ID;
            entityColumns[3] = MediaStore.Images.Media.DATE_ADDED;
            //entityColumns[3] = MediaStore.Images.Media.DATE_TAKEN;
            entityColumns[4] = MediaStore.Images.Media.SIZE;
            break;
        }
        case DELASHARE_OBJECT_APK:
        case DELASHARE_OBJECT_DOCUMENT:
        case DELASHARE_OBJECT_DOWNLOAD:
        case DELASHARE_OBJECT_SEARCH_RESULTS:
        default: {
            entityColumns[0] = MediaStore.Files.FileColumns.DISPLAY_NAME;
            entityColumns[1] = MediaStore.Files.FileColumns.DATA;
            entityColumns[2] = MediaStore.Files.FileColumns._ID;
            entityColumns[3] = MediaStore.Files.FileColumns.DATE_MODIFIED;
            entityColumns[4] = MediaStore.Files.FileColumns.SIZE;
            break;
        }
    }
    return (entityColumns);
}

public static Uri getCategoryUri(Constants.DELASHARE_OBJECT_TYPES categoryObjType) {
    Uri  objUri = null;

    switch(categoryObjType) {
        case DELASHARE_OBJECT_PICTURE:
            objUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            break;
        case DELASHARE_OBJECT_VIDEO:
            objUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            break;
        case DELASHARE_OBJECT_MUSIC:
            objUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            break;
        case DELASHARE_OBJECT_DOWNLOAD: {
            File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
            objUri = Uri.fromFile( downloadDir);
            //objUri = MediaStore.Files.getContentUri("external");
            break;
        }
        case DELASHARE_OBJECT_APK:
        case DELASHARE_OBJECT_DOCUMENT:
        case DELASHARE_OBJECT_SEARCH_RESULTS:
        default:
            objUri = MediaStore.Files.getContentUri("external");
            break;

    }

    return(objUri);
}

public  static long getFileId(Context context, String dirPath, String filePath, String fileName, Constants.DELASHARE_OBJECT_TYPES objType) {
    boolean fIDFound = false;
    long    id       = 0;
    if (!fIDFound) {
        String          sortOrder      = null;
        String[]        entityColumns  = getCombinedEntityColumns(objType);
        Uri             categoryUri    = getCategoryUri(objType);
        String          selection      = null;
        String[]        selectionArgs  = new String[]{Constants.DELA_PERCENT_STR + dirPath};
        ContentResolver cr             = context.getContentResolver();
        Cursor cursor = null;

        switch (objType) {
            case DELASHARE_OBJECT_PICTURE:
                selection = MediaStore.Images.Media.DATA + " LIKE ?";
                break;
            case DELASHARE_OBJECT_VIDEO:
                selection = MediaStore.Video.Media.DATA + " LIKE ?";
                break;
            case DELASHARE_OBJECT_DOCUMENT:
            default:
                selection = MediaStore.Files.FileColumns.DATA + " LIKE  ?";
                break;
        }
        cursor = cr.query(
                categoryUri,
                entityColumns,
                selection,
                selectionArgs,
                sortOrder);

        if (cursor != null && cursor.moveToFirst()) {
            id = cursor.getLong(cursor.getColumnIndex(entityColumns[2]));

            if (id != 0) {
                fIDFound = true;
            }
        }
        if (cursor != null) {
            cursor.close();
            cursor = null;
        }
    }
    return(id);

}
于 2019-01-15T10:59:04.130 回答
0

我现在和你有同样的问题,sendBroadcast 方法在 4.4 中被禁止,并在这里使用 Media Store 内容提供程序找到了一个很好的解决方案:https ://stackoverflow.com/a/20780472/1060805

我在 Android 4.4 上对其进行了测试,效果很好。我认为这是一个可靠的方法。

于 2014-02-12T17:09:41.263 回答
0

尝试

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

将此添加到您的清单中:

<intent-filter>
      <action android:name="android.intent.action.MEDIA_MOUNTED" />
      <data android:scheme="file" /> 
</intent-filter>
于 2016-09-21T10:56:36.523 回答