Android MediaProvider--文件管理:必现,文件管理器中新建几个文件夹,批量删除后,连接电脑查看仍有部分文件夹未删除
问题描述:
【测试步骤】:1、进入文件管理器中,新建几个文件夹,然后批量全选这些文件夹--删除;
2、手机连接电脑,在电脑端查看文件显示。
【测试结果】:电脑端查看仍有部分文件夹未删除。插拔USB线几次,在电脑端重新查看,仍显示。
【预期结果】:电脑端不应显示已删除的文件夹。
【复现概率】:100%(若第一次未复现,步骤1、2重新操作即可复现)
【备注】:在文件管理中点击“搜索”,也能搜索出这些文件夹。
按以下步骤更容易复现
1.添加一个本地文件夹,删除新添加的文件夹
2.再新建另一文件夹。(文件系统中文件夹已创建,且媒体库中已新增此记录,但操作1中被删除的文件夹,在媒体库中又出现了)
此问题是由于MediaProvider添加了线程池扫描引起的,Android原生的不会有这个问题,
解决办法:修改packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerThreadPool.java文件的内部类:
private class InsertFolderTask extends Task { private ContentResolver mContentResolver; // <2015.05.06> modify for start private boolean isExistInFileSystem(String folderPath) { return new File(folderPath).exists(); } //<2015.05.06> modify for end public InsertFolderTask() { super(PRIORITY_MAX + LESS_PRIOR, 0); mContentResolver = mContext.getContentResolver(); } @Override public void run() { long start = System.currentTimeMillis(); int size = mFolderMap.size(); List<ContentValues> folderList = new ArrayList<ContentValues>(size); Iterator<Entry<String, FolderStructure>> iterator = mFolderMap.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, FolderStructure> entry = iterator.next(); String folderPath = entry.getKey(); FolderStructure folderStructure = entry.getValue(); // <2015.05.06> modify for start /// If folder have been deleted right now, remove from map and do next check. if (!isExistInFileSystem(folderPath)) { iterator.remove(); continue; } // <2015.05.06> modify for end /// Root folder path(store in each directory) have been insert while begin scanning if (!isExistInDatabase(folderPath)) { ContentValues values = new ContentValues(); values.put(MediaStore.Files.FileColumns.TITLE, MediaFile.getFileTitle(folderPath)); values.put(MediaStore.Files.FileColumns.FORMAT, MtpConstants.FORMAT_ASSOCIATION); values.put(MediaStore.Files.FileColumns.DATA, folderPath); values.put(MediaStore.Files.FileColumns.DATE_MODIFIED, folderStructure.mLastModified); values.put(MediaStore.Files.FileColumns.SIZE, 0); values.put(MediaStore.Files.FileColumns.IS_DRM, 0); folderList.add(values); if (folderList.size() >= 500) { sortByPath(folderList); flush(MediaScannerInserter.FILE_URI, folderList); folderList.clear(); } } } if (!folderList.isEmpty()) { sortByPath(folderList); flush(MediaScannerInserter.FILE_URI, folderList); } /// Insert task finish, execute single type scan task. executeSingleTypeScanTask(); long end = System.currentTimeMillis(); MtkLog.v(TAG, "Insert all folder entries finsih in " + Thread.currentThread().getName() + ": folder size = " + mFolderMap.size() + ", insert num = " + folderList.size() + ", cost = " + (end - start) + "ms"); } private void sortByPath(List<ContentValues> list) { Collections.sort(list, new Comparator<ContentValues>() { public int compare(ContentValues old, ContentValues latest) { String oldPath = old.getAsString(MediaStore.Files.FileColumns.DATA); String latestPath = latest.getAsString(MediaStore.Files.FileColumns.DATA); if (latestPath != null && oldPath != null) { return oldPath.compareTo(latestPath); } return 0; }; }); } private boolean isExistInDatabase(String folderPath) { Cursor cursor = null; try { cursor = mContentResolver.query(MediaScannerInserter.FILE_URI, null, MediaStore.Files.FileColumns.DATA + "=?", new String[] {folderPath}, null, null); return cursor != null && cursor.moveToFirst(); } catch (Exception e) { MtkLog.e(TAG, "Check isExistInDatabase with Exception for " + folderPath, e); return true; } finally { if (cursor != null) { cursor.close(); } } } private void flush(Uri tableUri, List<ContentValues> list) { long start = System.currentTimeMillis(); int size = list.size(); ContentValues[] valuesArray = new ContentValues[size]; valuesArray = list.toArray(valuesArray); try { mContentResolver.bulkInsert(tableUri, valuesArray); } catch (Exception e) { MtkLog.e(TAG, "bulkInsert with Exception for " + tableUri, e); } long end = System.currentTimeMillis(); MtkLog.d(TAG, "flush " + tableUri + " with size " + size + " which cost " + (end - start) + "ms"); } }添加// <2015.05.06> modify for start
// <2015.05.06> modify for end
的修改
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。