java - 重命名由应用程序在 android 10 中创建的 Mediastore 文件。在 Android API 30 上工作,但在 API 29 中显示错误
问题描述
在这里,这个 renameFile(..) 函数在 Android API 30 中工作。但是,它在 Android API 29 中不起作用,并显示如下错误:
java.lang.IllegalArgumentException:不允许移动不属于明确定义的集合的内容://media/external/file/116
更新注意:
---开始---
为了使用 sdk-29,我们必须将 Uri 用作 extUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL),例如:
private static Uri extUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL);
代替下面的代码。并且还将MediaStore.Files.FileColumns更新为MediaStore.Downloads
---结束---
Uri extUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
String relativeLocation = Environment.DIRECTORY_DOWNLOADS + File.separator + "AppFolder";
函数重命名文件(...)
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;
}
函数 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:不允许移动不属于明确定义的集合的内容://media/external/file/116
因此,如果您使用该集合,则对于 Android Q 是不允许的;
Uri extUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
但是对于“定义明确的集合”是允许的,例如:
Uri extUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
// Use "Pictures/MyFolder" for RELATIVE_PATH
我留给你去寻找其他定义明确的集合。
为什么这仅适用于我不知道的 Android Q。
引用:
// 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");
}
如果重命名失败,请使用 SAF(如前所述)。如何在Android中重命名文件只知道它的媒体内容Uri
推荐阅读
- scala - IntelliJ 在返回类型为“Int”的方法末尾显示“:Unit”
- angular - Adding Captcha V2 in Angular has( Error: Missing required parameters: sitekey)
- api - 使用 Postman 下载 Excel 文件的 Azure 逻辑应用 API http 响应
- flutter - How to add login URL to button in flutter
- python - Argument 'open' has incorrect type (expected numpy.ndarray, got DataFrame)
- java - I am not getting any output when I try to run the .class File that was created from my .java file in terminal. The code is compiling just not printing
- python-3.x - Why is the button disappearing?
- reactjs - How to move React countdown timer to worker thread
- javascript - 将重点放在众多文本区域之一
- macos - 如何在 mac 上设置 IME 候选窗口位置?