【Android 文件管理】分区存储 ( 修改与删除图片文件 )_mediastore.images.media.删除-程序员宅基地

技术标签: Android 文件管理  MediaStore  分区存储  Android  

在这里插入图片描述

Android 分区存储系列博客 :


在上一篇博客 【Android 文件管理】分区存储 ( 创建与查询图片文件 ) 中 , 使用 MediaStore 在外置存储 SD 卡中的 Pictures 目录中 , 创建 了 image.jpg 图片文件 , 并进行了 查询 ;

本篇博客讲解使用 MediaStore 修改 , 删除 图片文件操作 ;





一、分区存储模式下使用 MediaStore 修改图片



将 /sdcard/Pictures/image/ 目录下的 image.jpg 修改为 image_update.jpg ;


分区存储机制中 , 删除图片文件 , 不能通过获取其绝对路径进行删除 , 必须先使用 MediaStore 查询到图片文件的 Uri , 然后通过 Uri 执行 删除 / 修改 图片文件的操作 ;


查询图片 : 查询图片文件的具体原理参考 【Android 文件管理】分区存储 ( 创建与查询图片文件 ) , 不再详细分析 ;

首先 , 调用 getContentResolver 方法获取 ContentResolver , 执行 query 查询方法 ; 传入 查询的 Uri , 指定要查询的列 , 查询语句, 查询参数 , 排列规则 , 5 5 5 个参数 , 查询结果是 Cursor 对象 ;

// 查询 SQLite 数据库
var cursor = contentResolver.query(
        // 指定要查询的 Uri
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        // 指定要查询的列
        null,
        // 指定查询语句
        "${MediaStore.Images.Media.DISPLAY_NAME}=?",
        // 指定查询参数
        arrayOf("image.jpg"),
        // 排序规则
        null
)

然后 , 从 Cursor 中获取 MediaStore.Images.Media._ID 字段对应的值 , 通过 ContentUris 的 withAppendedId 方法 , 将 _id 字段值转为 Uri , 并保存在外部变量中 ;

// 要删除的图片对应的 Uri, 需要先查询出来
var uri: Uri?= null

// 先获取该图片在数据库中的 id , 然后通过 id 获取 Uri
if (cursor != null && cursor.moveToFirst()){
    
    // 获取第 0 行 _id 所在列的值
    var id = cursor.getLong(
            // 获取 _id 所在列的索引
            cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
    )
    // 通过 _id 字段获取图片 Uri
    uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
    Log.i(TAG, "查询到的 Uri = $uri , 开始准备删除")
    // 关闭游标
    cursor.close()
}

得到了图片的 Uri 地址 , 就可以对图片进行 删除 / 修改 操作了 ; 在 分区存储机制 中 , 只能通过文件的 Uri 地址操作文件的 增 删 查 改 ;


修改图片 : 构造 ContentValues , 将 display_name 修改成 image_update , 设置 MediaStore.Images.ImageColumns.DISPLAY_NAME 字段对应的值为 “image_update.jpg” , 然后 调用 getContentResolver 方法获取 ContentResolver , 调用 update 方法 , 更新图片 Uri 对应的数据 , 将上述 ContentValues 更新到 Uri 对应的数据库表中 ;

// 修改图片
// 构造 ContentValues
var contentValues: ContentValues = ContentValues();
// 将 display_name 修改成 image_update
contentValues.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, "image_update.jpg")

// 修改文件名称
var row = contentResolver.update(uri!!, contentValues, null, null)
Log.i(TAG, "修改 uri = $uri 结果 row = $row")

查询 并 修改 图片文件代码示例 :

/**
 * 修改图片
 */
fun updateImages(){
    
    // 要删除的图片对应的 Uri, 需要先查询出来
    var uri: Uri?= null
    
    // 查询 SQLite 数据库
    var cursor = contentResolver.query(
            // 指定要查询的 Uri
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            // 指定要查询的列
            null,
            // 指定查询语句
            "${MediaStore.Images.Media.DISPLAY_NAME}=?",
            // 指定查询参数
            arrayOf("image.jpg"),
            // 排序规则
            null
    )
    
    // 先获取该图片在数据库中的 id , 然后通过 id 获取 Uri
    if (cursor != null && cursor.moveToFirst()){
    
        // 获取第 0 行 _id 所在列的值
        var id = cursor.getLong(
                // 获取 _id 所在列的索引
                cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
        )
        
        // 通过 _id 字段获取图片 Uri
        uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
        Log.i(TAG, "查询到的 Uri = $uri , 开始准备修改")
        // 关闭游标
        cursor.close()
    }
    
    // 修改图片
    // 构造 ContentValues
    var contentValues: ContentValues = ContentValues();
    // 将 display_name 修改成 image_update
    contentValues.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, "image_update.jpg")
    
    // 修改文件名称
    var row = contentResolver.update(uri!!, contentValues, null, null)
    Log.i(TAG, "修改 uri = $uri 结果 row = $row")
}
/**

日志打印结果 :

查询到的 Uri = content://media/external/images/media/53 , 开始准备修改
修改 uri = content://media/external/images/media/53 结果 row = 1

文件删除效果 : 在 /sdcard/Pictures/image/ 目录中 , image.jpg 文件已经被修改为 image_update.jpg 文件 ;

在这里插入图片描述





二、分区存储模式下使用 MediaStore 删除图片



将 /sdcard/Pictures/image/ 目录下的 image_update.jpg 文件删除 ;


分区存储机制中 , 删除图片文件 , 不能通过获取其绝对路径进行删除 , 必须先使用 MediaStore 查询到图片文件的 Uri , 然后通过 Uri 执行 删除 / 修改 图片文件的操作 ;


查询图片 : 查询图片文件的具体原理参考 【Android 文件管理】分区存储 ( 创建与查询图片文件 ) , 不再详细分析 ;

首先 , 调用 getContentResolver 方法获取 ContentResolver , 执行 query 查询方法 ; 传入 查询的 Uri , 指定要查询的列 , 查询语句, 查询参数 , 排列规则 , 5 5 5 个参数 , 查询结果是 Cursor 对象 ;

// 查询 SQLite 数据库
var cursor = contentResolver.query(
        // 指定要查询的 Uri
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        // 指定要查询的列
        null,
        // 指定查询语句
        "${MediaStore.Images.Media.DISPLAY_NAME}=?",
        // 指定查询参数
        arrayOf("image_update.jpg"),
        // 排序规则
        null
)

然后 , 从 Cursor 中获取 MediaStore.Images.Media._ID 字段对应的值 , 通过 ContentUris 的 withAppendedId 方法 , 将 _id 字段值转为 Uri , 并保存在外部变量中 ;

// 要删除的图片对应的 Uri, 需要先查询出来
var uri: Uri?= null

// 先获取该图片在数据库中的 id , 然后通过 id 获取 Uri
if (cursor != null && cursor.moveToFirst()){
    
    // 获取第 0 行 _id 所在列的值
    var id = cursor.getLong(
            // 获取 _id 所在列的索引
            cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
    )
    // 通过 _id 字段获取图片 Uri
    uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
    Log.i(TAG, "查询到的 Uri = $uri , 开始准备删除")
    // 关闭游标
    cursor.close()
}

得到了图片的 Uri 地址 , 就可以对图片进行 删除 / 修改 操作了 ; 在 分区存储机制 中 , 只能通过文件的 Uri 地址操作文件的 增 删 查 改 ;


删除图片 : 调用 getContentResolver 方法获取 ContentResolver , 直接删除之前查询出的图片 Uri 即可 ;

// 删除图片
var row = contentResolver.delete(uri!!, null, null)

Log.i(TAG, "删除 uri = $uri 结果 row = $row")

查询 并 删除 图片文件代码示例 :

/**
 * 删除图片
 */
fun deleteImages(){
    
    // 要删除的图片对应的 Uri, 需要先查询出来
    var uri: Uri?= null
    
    // 查询 SQLite 数据库
    var cursor = contentResolver.query(
            // 指定要查询的 Uri
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            // 指定要查询的列
            null,
            // 指定查询语句
            "${MediaStore.Images.Media.DISPLAY_NAME}=?",
            // 指定查询参数
            arrayOf("image_update.jpg"),
            // 排序规则
            null
    )
    
    // 先获取该图片在数据库中的 id , 然后通过 id 获取 Uri
    if (cursor != null && cursor.moveToFirst()){
    
        // 获取第 0 行 _id 所在列的值
        var id = cursor.getLong(
                // 获取 _id 所在列的索引
                cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
        )
        
        // 通过 _id 字段获取图片 Uri
        uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
        Log.i(TAG, "查询到的 Uri = $uri , 开始准备删除")
        // 关闭游标
        cursor.close()
    }
    
    // 删除图片
    var row = contentResolver.delete(uri!!, null, null)
    Log.i(TAG, "删除 uri = $uri 结果 row = $row")
}

日志打印结果 :

查询到的 Uri = content://media/external/images/media/53 , 开始准备删除
删除 uri = content://media/external/images/media/53 结果 row = 1

文件删除效果 : 在 /sdcard/Pictures/image/ 目录中 , image_update.jpg 文件已经被删除 ;

在这里插入图片描述





三、相关文档资料



Android 文件处理参考文档 :


博客源码 :

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/han1202012/article/details/117116388

智能推荐

ESP8266学习——AP UDP Client_esp8226 udp client-程序员宅基地

文章浏览阅读338次。AP UDP Client内容步骤效果代码头文件宏定义全局变量关于ESP8266的代码ESP8266_AP_initESP8266_WIFI_Send_CbESP8266_WIFI_Recv_CbESP8266_NetCon_initOS_Timer_1_cbuser_init整体代码总结框架内容步骤同上一篇AP UDP Server几乎一样只是需要设置目标IP地址 ST_NetCon.proto.udp->remote_port = 8888; // 设置目标端口 ST_NetCon._esp8226 udp client

ftp 文件下载 linux,linux ftp命令使用,下载文件-程序员宅基地

文章浏览阅读552次。linux ftp命令使用,下载文件Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件Linux ftp命令的一般格式如下:$ ftp 主机名/IP最常用的命令有:ls 列出远程机的当前目录cd 在远程机上改变工作目录lcd 在本地机上改变工作目录ascii 设置文件传输方式为ASCII模式binary 设置文件传输方式为二进制模式close 终止当前的ftp会话has..._linux ftp下载文件目录的命令

Lambda表达式四大核心函数式接口——Java8新特性-程序员宅基地

文章浏览阅读309次。package com.atguigu.java8;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.function.Consumer;import java.util.function.Function;import java.util.functi...

读取多行数据到vector_不断读数据 vector-程序员宅基地

文章浏览阅读780次。要读取多行数据到vector,但是每行的数据个数又不一样,可以用到istringstream,先读取一行字符串,然后转化为字符串流,再从istringstream中读取数据#include<iostream>#include<string>#include<sstream>#include<vector>using namespac..._不断读数据 vector

mysql中int型和sqlserver中int_SQL里的int类型-程序员宅基地

文章浏览阅读470次。展开全部int、bigint、smallint 和 tinyint使用整数数据的精确数字数据类型。bigint从 -2^62616964757a686964616fe58685e5aeb93133336566356263 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字)。存储大小为 8 个字节。int从 -2^31 ...

[Patch]Redmine3.3.3分组查询结果默认折叠[草稿]-程序员宅基地

文章浏览阅读106次。为什么80%的码农都做不了架构师?>>> ..._redmine 任务折叠

随便推点

Android-自定义插件---彻底解决method-not-found-问题,android音视频开发方向_method not found: 'system.string system.appdomains-程序员宅基地

文章浏览阅读442次。基础库在迭代升级的时候 很可能要对某些方法进行修改,比如修改方法的返回值 ,修改方法的参数,甚至于要删除方法等等,但是如果你碰到上述的场景就要小心了,因为很多业务仓 依赖的还是老版本的基础库,他们运行是正常的,而你的新版本的基础库版本号提高以后删除了某个方法,假设他们又用到了这个方法,那么实际运行的时候 就会报method not found的 错误了。有人问 那你每次升级基础库的时候强制要求业务仓也跟着升级不就行了?当然是不行的。。。因为很多都是跨部门的业务,没有合理的理由 他们是不愿意 每次都跟着你的_method not found: 'system.string system.appdomainsetup.get_configurationfile

MATLAB GUI设计II 多功能模式题目生成器 四则运算 | 界面切换 | 字符串处理 | cell数组 | GUI_matlab算数题生成器-程序员宅基地

文章浏览阅读1.3k次,点赞9次,收藏12次。本GUI支持 界面切换 、界面可视化操作、基于cell数组的多数据存储与处理、混合模式选择、无括号的二级四则混合运算、多弹出式菜单选择、多单选按钮、多复选框、字符串处理、生成导出及引用文件 ;版本为R2018b 中文版本_matlab算数题生成器

实验吧-简单的登录题——WriteUp再研究_信安三勇-程序员宅基地

文章浏览阅读6.1k次,点赞3次,收藏12次。前言这个题目的难点就是在于对于CBC加密方式尤其是解密这部分要琢磨一番,让我想起当年大学的时候信安三勇中的两勇的课,一门密码学,一门数学基础,可怕之极。这个题网上writeup一大堆,但是在一些方面解释的不是很详细,对大神们已经说的很清楚的地方我就粗略带过。CBC解密以及字节翻转攻击(cbc-byte-flipping-attack)我主要以CBC字符翻转 原理与实战这篇文章为基础..._信安三勇

++x和x++的区别_python中y=++x-程序员宅基地

文章浏览阅读1.5w次,点赞10次,收藏24次。很多时候搞不清楚++x和x++的区别,其实只要多熟悉熟悉就能搞清楚了,x++是在进行其他操作之后,再给x加一,++x正好与其相反 int x=1;int y=2;int z=3;y=++x; //此处为第一情况,输出的值应该为2,2 因为x先自增,然后加一y=x++; //此处的值为1,2,因为计算步骤为先赋值再自增System.out.p_python中y=++x

来来来~ 码一万字,带你读懂JWT_jwt.decode-程序员宅基地

文章浏览阅读2.2k次。1. 为什么要用 JWT ?认证在谈起 JWT 之前,我们先了解一下什么是认证。在登录淘宝、微博等软件或者网站之前,我们需要通过填写账号和密码来校验身份。认证是用来验证用户身份合法性的一种方式。那我们登录成功之后,网站如何记录我们的身份信息呢?前面我们在学习 servlet 的时候,知道了传统的系统主要是通过 session 来存储用户的信息。session 将用户的信息存储在服务端。但是随着用户数量的增多,服务端就需要存一堆用户的认证信息,这种方式会不断增加服务端的压力.._jwt.decode

CESIUM例子学习(九)——Primitive(3)_polylinevolumegeometry-程序员宅基地

文章浏览阅读4.5k次。geometry实在是太多了,多也要一个一个地学。学习的过程中不仅仅是用Primitive加载各种geometry。在这个过程中也加深对cesium的印象,至少混过脸熟,然后熟就能生巧。特别是学习这种事,要自己亲手去做去练习才能有更好的体会。一、Polyline(线)cesium提供了SimplePolylineGeometry、PolylineGeometry、PolylineVolumeGeometry、PolylineVolumeOutlineGeometry、GroundP..._polylinevolumegeometry