问题现象:手机连接电脑–电脑端打卡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); } }