简体   繁体   English

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

[英]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:相反,我不得不:

  1. 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)
  2. Initialize 'extUri' with that second value, like that:用第二个值初始化“extUri”,如下所示:

     extUri = MediaStore.Audio.Media.getContentUri("bc21-eafa");
  3. Apply the rest of the procedure as described in this article.按照本文中的说明应用其余过程。 Thanks to all !谢谢大家 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我正在尝试在我的 Android 10 设备上运行该应用程序并显示以下错误 - minSdk(API 30) &gt; deviceSdk(API 29) - I am trying to run the app on my Android 10 device and the following error is shown - minSdk(API 30) > deviceSdk(API 29) 更新 MediaStore 上的条目不适用于 Android Q/API29 - Updating an entry on MediaStore does not work on Android Q / API29 Android 10 (API 29) 升级后 setColor 不起作用 - setColor not working after Android 10 (API 29) upgrade boot_completed 不工作 Android 10 Q API 级别 29 - boot_completed not working on Android 10 Q API level 29 使用 MediaStore 和 ContentValues 在 Android 11 / API 30 上重命名视频 - Video renaming on Android 11 / API 30 using MediaStore and ContentValues Picasso 在 android 10 中不工作。为什么? - Picasso is not working in android 10. Why? HttpsURLConnection不适用于Android API 19(但适用于API 22至29) - HttpsURLConnection not working on Android API 19 (but works on API 22 through 29) requestLegacyExternalStorage 在 Android 11 - API 30 中不起作用 - requestLegacyExternalStorage is not working in Android 11 - API 30 WebView.loadData 不适用于 Android 9.0 (API-29) - WebView.loadData not working on Android 9.0 (API-29) 无法使用 API 29 android studio 在模拟器中运行应用程序 - Unable to run app in emulator with API 29 android studio
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM