简体   繁体   English

使用 MediaStore 和 ContentValues 在 Android 11 / API 30 上重命名视频

[英]Video renaming on Android 11 / API 30 using MediaStore and ContentValues

The codes below works fine prior to Android 11. I have tested it on Android 9 and it works.下面的代码在 Android 11 之前可以正常工作。我已经在 Android 9 上对其进行了测试,并且可以正常工作。
Method to get basic info about the video:获取视频基本信息的方法:

private static void videoRename ( AppCompatActivity activity , VideoModel model , VideosLoader videosLoader ) {
        String videoTitleWithExtension =  model.getVideoTitle ( );
        int extensionIndex = videoTitleWithExtension.lastIndexOf ( '.' );
        final String videoTitleWithoutExtension;
        String extensionValue;
        if ( extensionIndex > 0 ) {
            videoTitleWithoutExtension = videoTitleWithExtension.substring ( 0 , extensionIndex );
            extensionValue = videoTitleWithExtension.substring ( extensionIndex, videoTitleWithExtension.length ( ) );
        } else {
            videoTitleWithoutExtension = videoTitleWithExtension;
            extensionValue = "";
        }

        showSelectedVideoRenameDialog ( activity , videoTitleWithoutExtension, model.getPath ( ) , extensionValue, model.getVideoId ( ) , videosLoader );

}

passing data to the dialog, then showing the dialog:将数据传递给对话框,然后显示对话框:

private static void showSelectedVideoRenameDialog ( final AppCompatActivity activity, final String videoTitleWithoutExtension , final String videoPath, final String extensionValue, final long videoId , final VideosLoader videosLoader ) {
        final AlertDialog dialog = new AlertDialog.Builder ( activity ).create ( );
        LayoutInflater inflater = LayoutInflater.from ( activity );
        View v = inflater.inflate ( R.layout.layout_video_rename, null );
        final TextInputEditText input = v.findViewById ( R.id.video_rename_edit_text );
        input.setText ( videoTitleWithoutExtension );
        input.setHint ( videoTitleWithoutExtension );

        Button confirmButton = v.findViewById ( R.id.renameButton );
        Button cancelButton = v.findViewById ( R.id.cancelButton );

        dialog.setView ( v );
        cancelButton.setOnClickListener ( new View.OnClickListener ( ) {
            @Override
            public void onClick ( View p1 ) {
                dialog.dismiss ( );
            }
        } );

        confirmButton.setOnClickListener ( new View.OnClickListener ( ) {
            @Override
            public void onClick ( View p1 ) {
                final String typedName = input.getText ( ).toString ( );
                final File originalName = new File ( videoPath );
                final File newFileName = new File ( videoPath.replace ( videoTitleWithoutExtension , typedName ) );
                if ( typedName.length ( ) == 0 ) {
                    input.setError ( "Name can't be empty" );
                } else if ( newFileName.exists ( ) ) {
                    input.setError ( "File name already exists" );
                } else {
                    String newTitleWithExtension = typedName + extensionValue;
                    originalName.renameTo ( newFileName );
                    String newFilePath = newFileName.toString ( );
                    videosLoader.updateOnVideoRenamed ( videoId , newFilePath , newTitleWithExtension );
                    videosLoader.updateOnMediaStoreChanged ( );

                    dialog.dismiss ( );
                }
            }
        } );
        dialog.show ( );
}

Finally, updating the values using ContentValues and MediaStore :最后,使用ContentValuesMediaStore更新值:

@Override
    public void updateOnVideoRenamed ( long id, String newPath, String newTitle ) {
        try {
            ContentValues contentValues = new ContentValues(2);
            contentValues.put(MediaStore.Video.Media.DATA, newPath);
            contentValues.put(MediaStore.Video.Media.DISPLAY_NAME, newTitle);
            mContext.getContentResolver ( ).update ( MediaStore.Video.Media.EXTERNAL_CONTENT_URI , contentValues, MediaStore.Video.Media._ID + "=" + id, null );
        } catch (Exception e) {
            Toast.makeText( mContext , "Can't rename on Android 11: " + " " + e.getMessage() , Toast.LENGTH_SHORT).show();
        }
}

This final step obviously throws the java.lang.IllegalArgumentException .这最后一步显然会抛出java.lang.IllegalArgumentException
I tried the answer here but still in vain.我在这里尝试了答案,但仍然是徒劳的。 I might be missing something.我可能会遗漏一些东西。
PS Renaming also fails for the videos inside folders I created using the default Samsung File manager.对于我使用默认三星文件管理器创建的文件夹中的视频,PS 重命名也失败了。

First of all, I had to add this permission to manifest in order to be able to access all files on device:首先,我必须将此权限添加到清单,以便能够访问设备上的所有文件:

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

Then I added this line to application tag:然后我将此行添加到application标签:

android:requestLegacyExternalStorage="true"

Now after you change the name of the video, you need to update the media store with the new name:现在,在您更改视频名称后,您需要使用新名称更新媒体存储:

if (ContextUtils.isAndroidR()) {
            Uri mUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI , videoId);
            try {
                ContentValues contentValues = new ContentValues(3);
                contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
                mContext.getContentResolver().update(mUri, contentValues, null, null);
                contentValues.clear();
                contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, newTitle);
                contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
                mContext.getContentResolver().update(mUri, contentValues, null, null);
            } catch (Exception exception) {
                if (ContextUtils.isAndroidQ()) {
                    RecoverableSecurityException recoverableSecurityException;
                    if (exception instanceof RecoverableSecurityException) {
                        recoverableSecurityException = (RecoverableSecurityException) exception;
                    } else {
                        ContextUtils.makeShortToast( "Maybe make sure you request permissions first?" );
                    }
                    try {
                        ContentResolver contentResolver = mContext.getContentResolver();
                        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, newTitle);
                        contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
                        contentResolver.update(mUri, contentValues, null, null);
                    } catch (Exception e) {
                        e.printStackTrace();
                        ContextUtils.makeShortToast( String.valueOf(e) );
                    }
                } else {
                    throw new RuntimeException ( exception.getMessage() , exception );
                }
            }
        } else {
            ContentValues contentValues = new ContentValues(2);
            contentValues.put(MediaStore.Video.Media.DATA, newPath);
            contentValues.put(MediaStore.Video.Media.DISPLAY_NAME, newTitle);
            Uri extUri = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
            mContext.getContentResolver().update(extUri , contentValues, MediaStore.Video.Media._ID + "=" + videoId, null);
        }

This is how I got renaming a video on Android 11 to work with no issues.这就是我如何重命名 Android 11 上的视频以正常工作。

暂无
暂无

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

相关问题 如何使用 MediaStore API 访问 Android 11 的 Whatsapp 文件夹? - How to access Whatsapp folder of Android 11 by using MediaStore API? 如何在 android 工作室中使用 MediaStore Api 在 android 11 中获取特定文件夹,如 WhatsApp (.Status) 文件夹 - How to get specific folder like WhatsApp (.Status) folder in android 11 using MediaStore Api in android studio 使用 MediaStore.createDeleteRequest() 在 android 11 中未删除文件 - Files not being deleted in android 11 using MediaStore.createDeleteRequest() 公共存储文件夹 API 30 Android 11 - Public Storage Folder API 30 Android 11 requestLegacyExternalStorage 在 Android 11 - API 30 中不起作用 - requestLegacyExternalStorage is not working in Android 11 - API 30 重命名由应用程序在 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 正确查询 Android 11 上的 MediaStore 记录 - Properly querying MediaStore records on Android 11 在 Android 11 (API 30) 中以编程方式更改状态栏文本颜色 - Programmatically Change Status Bar Text Color in Android 11 (API 30) 不适用于 android 11 (api 30) 上的对讲 12.2 的可点击跨度 - Not works clickable spans with talkback 12.2 on android 11 (api 30) android 11 (api 30): 后台服务录音不工作 - android 11 (api 30): recording voice in background service no working
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM