java - 重命名由应用程序在 android 10 中创建的 Mediastore 文件。在 Android API 30 上工作,但在 API 29 中显示错误

标签 java android file-rename mediastore android-10.0

在这里,这个 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: Movement of content://media/external/file/116 which isn't part of well-defined collection not allowed



因此,如果您使用该集合,则对于 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。
在java文件中可以看到消息:https://android.googlesource.com/platform/packages/providers/MediaProvider/+/refs/heads/master/src/com/android/providers/media/MediaProvider.java
引用:
     // 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(如前所述)。 How to rename a file in Android knowing only its media content Uri

关于java - 重命名由应用程序在 android 10 中创建的 Mediastore 文件。在 Android API 30 上工作,但在 API 29 中显示错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63543414/

相关文章:

java - 在 Query Vertices() 中获取空值 - 英特尔实感 F200

Java.util.Arrays.sort - 什么类型?

java - Junit 测试,其中一些参数不同而其他参数保持不变

android - 在 Android x86 上开发 Android 应用

android - 为什么 AlarmManager 警报在第一次运行时延迟?

android - switch语句不切换

windows - 在 Emacs 中重新排列文件名

java - 播种 Java Random 时的奇怪行为

javascript - 在 Node.js 中重命名文件而不使用 fs

python-3.x - 尝试使用 os.rename 重命名文件会引发 FileNotFoundError : [Errno 2]