问题描述:
【测试步骤】: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 folderList = new ArrayList(size);
Iterator> iterator = mFolderMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry 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 list) {
Collections.sort(list, new Comparator() {
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 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
的修改