问题现象:手机连接电脑–电脑端打卡SD卡–新建文件夹–重命名之后会弹出一个对话框提示错误,重新链接usb之后查看文件夹其实已经重命名成功
问题分析:
01-03 00:59:23.132 5089 5490 E MtpDatabaseJNI: An exception was thrown by callback 'setObjectPropertyValue'.
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: java.lang.IllegalArgumentException: Requested path /mnt/media_rw/E0CE-13E7/asdfasas doesn't appear under [/storage/E0CE-13E7]
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at com.android.providers.media.MediaProvider.updateInternal(MediaProvider.java:4722)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at com.android.providers.media.MediaProvider.update(MediaProvider.java:4486)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at android.content.ContentProvider$Transport.update(ContentProvider.java:420)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at android.content.ContentProviderClient.update(ContentProviderClient.java:376)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at android.mtp.MtpDatabase.renameFile(MtpDatabase.java:579)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at android.mtp.MtpDatabase.setObjectProperty(MtpDatabase.java:698)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at android.mtp.MtpServer.native_run(Native Method)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at android.mtp.MtpServer.run(MtpServer.java:116)
01-03 00:59:23.134 5089 5490 E MtpDatabaseJNI: at java.lang.Thread.run(Thread.java:919)
从log中看到 /mnt/media_rw/E0CE-13E7/asdfasas doesn’t appear under [/storage/E0CE-13E7] 两个路径不匹配导致无法出错,原因应该是在
frameworks/base/core/java/android/os/storage/VolumeInfo.java 中路径给改了
public File getInternalPathForUser(int userId) {
if (path == null) {
return null;
} else if (type == TYPE_PUBLIC || type == TYPE_STUB) {
// TODO: plumb through cleaner path from vold
return new File(path.replace("/storage/", "/mnt/media_rw/")); // 这里把路径改了
} else {
return getPathForUser(userId);
}
}
修改方法如下,不确定是否会有其他问题:
packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
private static void assertFileColumnsSane(int match, Uri uri, ContentValues values)
throws VolumeArgumentException {
if (!values.containsKey(MediaColumns.DATA)) return;
try {
// Sanity check that the requested path actually lives on volume
final String volumeName = resolveVolumeName(uri);
final Collection<File> allowed = getVolumeScanPaths(volumeName);
- final File actual = new File(values.getAsString(MediaColumns.DATA))
+ final File actual = new File(values.getAsString(MediaColumns.DATA).replaceAll("/mnt/media_rw/", "/storage/"))
.getCanonicalFile();
if (!FileUtils.contains(allowed, actual)) {
throw new VolumeArgumentException(actual, allowed);
}
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}