【问题标题】:MediaStore returned thumbnail path but File object giving file not exist - AndroidMediaStore 返回了缩略图路径,但提供文件的文件对象不存在 - Android
【发布时间】:2016-07-19 17:06:43
【问题描述】:

我使用CursorLoader 获得了视频的缩略图路径。 MediaStore 给了我缩略图路径。现在当我检查缩略图路径是否存在时,它给了我file not exists

我找到了缩略图路径使用

Cursor c = new CursorLoader(getApplicationContext(), MediaStore.Video.Thumbnails.getContentUri("external"), project,  selection, selectionArgs, null).loadInBackground();
while(c.moveToNext()) {

    //Toast.makeText(getApplicationContext(), c.getString(1),Toast.LENGTH_LONG).show();
    paths=c.getString(1);
 }

Toasts 显示类似的路径

/storage/emulated/0/DCIM/.thumbnails/1411810114902.jpg

所以我决定在处理文件之前检查文件是否存在。

File file = new File(paths);
if (file.exists())
{
     Toast.makeText(getApplicationContext(), "YES",Toast.LENGTH_LONG).show();
}
else
{
    Toast.makeText(getApplicationContext(), "NO",Toast.LENGTH_LONG).show();
}

令人惊讶的是,它显示NO 如何!什么媒体商店给了我?我的主要目的是将缩略图图像操作或转换为 base64 字符串。但是decodeFile 方法给出了File not exists 错误,所以我尝试检查该文件是否存在。

当 mediaStore 给出文件路径时,为什么会出现类似文件不存在的错误。这是怎么回事?我错过了什么?操作/访问缩略图的方法是什么?

【问题讨论】:

  • 做所有的缩略图,有同样的问题吗?有时,删除图像后媒体存储数据库不会更新。
  • 是的。如果我将文件检查放在循环中,所有路径都显示NO
  • 你能显示你的整个代码游标加载器中的每个对象是什么你能显示相应的值吗?

标签: android mediastore


【解决方案1】:

当用户从文件管理器中删除图像文件时会发生这种情况,并且如果文件管理器未发送适当的广播通知媒体扫描仪,则此图像的缩略图信息仍将存在于提供程序中。

我也遇到过类似的问题,我只想获取sdcard上还存在的图片,因为我想把所有的图片都显示在一个网格中,然后当用户点击一个item的时候,让用户查看大图图像,但有些图像只有拇指,而不是真实图像。

首先值得注意的是,修改CursorLoader中的选择参数是行不通的,因为我们不能让CursorLoader来检查文件是否存在。 我的解决方法是使用自定义的CursorWrapper 跳过包含坏文件的行

public class CursorWithDefectiveRows extends CursorWrapper {
    private static final String TAG = CursorWithDefectiveRows.class.getSimpleName();

    private Cursor mCursor;
    private DefectiveCursorRowChecker mChecker;
    private List<Integer> mGoodRowCounts;

    private Map<Integer, Integer> mCache;


    public static interface DefectiveCursorRowChecker {
        boolean isDefective(Cursor cursor);

        public static final DefectiveCursorRowChecker IMAGE_FILE_EXISTS_CHECKER = new DefectiveCursorRowChecker() {
            @Override
            public boolean isDefective(Cursor cursor) {
                File imageFile = new File(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)););
                return !(imageFile.exists() && imageFile.length() > 0);
            }
        };
    }


    public CursorWithDefectiveRows(Cursor cursor, DefectiveCursorRowChecker checker) {
        super(cursor);

        mCursor = cursor;
        mChecker = checker;

        init(cursor, checker);
    }

    private void init(Cursor cursor, DefectiveCursorRowChecker checker) {
        mGoodRowCounts = new ArrayList<>();


        mGoodRowCounts.add(0);

        for (int i = 0; i < cursor.getCount(); i++) {
            cursor.moveToPosition(i);
            if (checker.isDefective(cursor)) {
                mGoodRowCounts.add(mGoodRowCounts.get(i));
            } else {
                mGoodRowCounts.add(mGoodRowCounts.get(i) + 1);
            }
        }

        mCache = new HashMap<>();
    }

    public int getCompressedPosition(int cursorPosition) {
        return mGoodRowCounts.get(cursorPosition);
    }

    public int getCursorPosition(int compressedPosition) {
        if (compressedPosition < 0) {
            return -1;
        }

        if (compressedPosition > getCount() - 1) {
            return mCursor.getCount();
        }

        if (mCache.containsKey(compressedPosition)) {
            return mCache.get(compressedPosition);
        }

        int index = Collections.binarySearch(mGoodRowCounts, compressedPosition);
        if (index < 0) {
            return index;
        }

        while (index < mGoodRowCounts.size() - 1 && mGoodRowCounts.get(index).intValue() == mGoodRowCounts.get(index + 1).intValue()) {
            index++;
        }

        mCache.put(compressedPosition, index);
        return index;
    }

    @Override
    public int getCount() {
        return mGoodRowCounts.get(mGoodRowCounts.size() - 1);
    }

    @Override
    public int getPosition() {
        return getCompressedPosition(mCursor.getPosition());
    }

    @Override
    public boolean move(int offset) {
        return moveToPosition(getPosition() + offset);
    }

    @Override
    public boolean moveToPosition(int position) {
        return mCursor.moveToPosition(getCursorPosition(position));
    }

    @Override
    public boolean moveToFirst() {
        return moveToPosition(0);
    }

    @Override
    public boolean moveToLast() {
        return moveToPosition(getCount() - 1);
    }

    @Override
    public boolean moveToNext() {
        return moveToPosition(getPosition() + 1);
    }

    @Override
    public boolean moveToPrevious() {
        return moveToPosition(getPosition() - 1);
    }

    @Override
    public boolean isFirst() {
        return getPosition() == 0;
    }

    @Override
    public boolean isLast() {
        return getPosition() == getCount() - 1;
    }


    @Override
    public boolean requery() {
        boolean result = super.requery();

        if (result) {
            init(mCursor, mChecker);
        }

        return result;
    }



}

这个类的主要工作发生在initgetCursorPosition 方法中,我现在不在这里解释,毕竟它们不是很复杂。 要使用这个类,只需使用

Cursor cursor = new CursorWithDefectiveRows(loadedCursor, CursorWithDefectiveRows.DefectiveCursorRowChecker.IMAGE_FILE_EXISTS_CHECKER)

这个结果光标会跳过所有坏文件,它可以立即与CursorAdapter一起使用

【讨论】:

  • @Skullper 哎呀,我很遗憾现在代码不是很复杂,那里肯定有一些复杂的东西。但是我仍然在我的 s9+ 上开发了 2 年前的应用程序,而且它看起来运行良好。
【解决方案2】:

几天前我遇到了同样的问题。原因是由于一些内部内存管理过程,有时它将图像存储在/storage/emulated/0/DCIM/storage/emulated/1/DCIM

为了解决这个问题,它始终建议创建新文件夹以保存从相机新捕获的图像并从该文件夹访问它

另外,在真实设备上检查它可能是因为没有用于模拟器的 sd 卡,所以如果内存已满,它会混淆存储位置,所以它会跳转到 sd 卡 dcim 文件夹。

【讨论】:

  • 无论它保存在哪里,mediaStore 都不应该给我正确的路径吗?我的路径不是静态的,它们是从 mediaStore 查询中收集的。缩略图不是来自捕获的图像/视频。这些是保存在 sdcard 中的视频。下载/传输的视频可以在那里。所以我无法控制缩略图的保存位置。
  • 在真机上查看可能是因为模拟器没有sd卡
  • 如果内存已满,它会混淆存储位置,所以它会跳转到 sd 卡 dcim 文件夹
  • 是的,在真实设备上工作。奇怪的!!!!!!!这些路径也是从模拟器生成的。怎么会生成自己找不到的路径。有趣的!反正解决了。谢谢你。你可以用你的建议更新答案,我会接受的。
  • 感谢赞赏
猜你喜欢
  • 2014-10-30
  • 2018-03-11
  • 1970-01-01
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多