[英]Rename file of the Mediastore which is created by app in android 10. Working on Android API 30 but shows error in API 29
Here, this renameFile(..) func is working in Android API 30. But, it is not working in Android API 29 and shows the error like :在这里,这个 renameFile(..) 函数在 Android API 30 中工作。但是,它在 Android API 29 中不起作用,并显示如下错误:
java.lang.IllegalArgumentException: Movement of content://media/external/file/116 which isn't part of well-defined collection not allowed java.lang.IllegalArgumentException:不允许移动不属于明确定义的集合的内容://media/external/file/116
Update-Note:更新注意:
---Begins--- ---开始---
In-order to work with sdk-29 we have to use Uri as extUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL) like:为了使用 sdk-29,我们必须将 Uri 用作 extUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL),例如:
private static Uri extUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL);
in place of below code.代替下面的代码。 And also update MediaStore.Files.FileColumns to MediaStore.Downloads
并且还将MediaStore.Files.FileColumns更新为MediaStore.Downloads
---Ends--- ---结束---
Uri extUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
String relativeLocation = Environment.DIRECTORY_DOWNLOADS + File.separator + "AppFolder";
function renameFile(...)函数重命名文件(...)
boolean renameFile(Context context, String newName, String displayName) {
try {
Long id = getIdFromDisplayName(displayName);
ContentResolver contentResolver = context.getContentResolver();
Uri mUri = ContentUris.withAppendedId(extUri, id);
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
contentResolver.update(mUri, contentValues, null, null);
contentValues.clear();
contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, newName);
// contentValues.put(MediaStore.Files.FileColumns.MIME_TYPE, "files/pdf");
// contentValues.put(MediaStore.Files.FileColumns.RELATIVE_PATH, relativeLocation);
// contentValues.put(MediaStore.Files.FileColumns.TITLE, "SomeName");
// contentValues.put(MediaStore.Files.FileColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
// contentValues.put(MediaStore.Files.FileColumns.DATE_TAKEN, System.currentTimeMillis());
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
contentResolver.update(mUri, contentValues, null, null);
return true;
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
function getIdFromDisplayName(...)函数 getIdFromDisplayName(...)
@RequiresApi(api = Build.VERSION_CODES.Q)
Long getIdFromDisplayName(String displayName) {
String[] projection;
projection = new String[]{MediaStore.Files.FileColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = getContentResolver().query(extUri, projection,
MediaStore.Files.FileColumns.DISPLAY_NAME + " LIKE ?", new String[]{displayName}, null);
assert cursor != null;
cursor.moveToFirst();
if (cursor.getCount() > 0) {
int columnIndex = cursor.getColumnIndex(projection[0]);
long fileId = cursor.getLong(columnIndex);
cursor.close();
return fileId;
}
return null;
}
java.lang.IllegalArgumentException: Movement of content://media/external/file/116 which isn't part of well-defined collection not allowed
java.lang.IllegalArgumentException:不允许移动不属于明确定义集合的内容://media/external/file/116
So it is for Android Q not allowed if you use the collection;因此,如果您使用该集合,则不允许用于 Android Q;
Uri extUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
But is is allowed for a 'well-defined collection' like:但是允许用于“定义明确的集合”,例如:
Uri extUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
// Use "Pictures/MyFolder" for RELATIVE_PATH
I leave it to you to find other well-defined collections.我把它留给你去寻找其他定义明确的集合。
Why this is only for Android Q i dont know.为什么这仅适用于 Android Q,我不知道。
You can see the message in the java file: https://android.googlesource.com/platform/packages/providers/MediaProvider/+/refs/heads/master/src/com/android/providers/media/MediaProvider.java您可以在java文件中看到消息: https : //android.googlesource.com/platform/packages/providers/MediaProvider/+/refs/heads/master/src/com/android/providers/media/MediaProvider.java
Quote:引用:
// We only support movement under well-defined collections
switch (match) {
case AUDIO_MEDIA_ID:
case VIDEO_MEDIA_ID:
case IMAGES_MEDIA_ID:
case DOWNLOADS_ID:
break;
default:
throw new IllegalArgumentException("Movement of " + uri
+ " which isn't part of well-defined collection not allowed");
}
If the rename fails use SAF (as mentioned before).如果重命名失败,请使用 SAF(如前所述)。 How to rename a file in Android knowing only its media content Uri
如何在仅知道其媒体内容 Uri 的 Android 中重命名文件
I had to face the rename problem myself (Android 29) and the solution above did not suffice.我不得不自己面对重命名问题(Android 29),上面的解决方案还不够。
This was because I had a physical SD card on which were located the files I wanted to rename.这是因为我有一个物理 SD 卡,上面有我想要重命名的文件。
Then, instruction:然后,指令:
extUri = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
did not work;不工作; instead,I had to:
相反,我不得不:
list the "external volumes"(according to Android terms)列出“外部卷”(根据 Android 条款)
Set<String> lVls = MediaStore.getExternalVolumeNames(this);
..which gave me 2 volumes: ..这给了我2卷:
"external_primary" (the built-in external storage) "bc21-eafa" (the SD card external storage)
Initialize 'extUri' with that second value, like that:用第二个值初始化“extUri”,如下所示:
extUri = MediaStore.Audio.Media.getContentUri("bc21-eafa");
Apply the rest of the procedure as described in this article.按照本文中的说明应用其余过程。 Thanks to all !
谢谢大家 !
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.