当前位置: 首页 > 知识库问答 >
问题:

范围存储:如何通过纵隔删除多个音频文件?

秦建元
2023-03-14

我试图从设备的外部存储中删除音频文件(例如/storage/emulated/0/music文件夹中)。在分析了mediastore示例之后,我最终得到了以下API 28及更早版本的解决方案:

fun deleteTracks(trackIds: LongArray): Int {
    val whereClause = buildWildcardInClause(trackIds.size) // _id IN (?, ?, ?, ...)
    return resolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, whereClause, Array(trackIds.size) { trackIds[it].toString() })
}

我注意到上面的代码只从纵隔数据库中删除曲目,而不从设备中删除(文件在重新引导后重新添加到纵隔中)。因此,我修改了该代码以查询media.data列,然后使用该信息删除相关文件。这按预期工作。

但是现在Android Q引入了作用域存储,media.data(和albums.album_art)现在不推荐使用,因为应用程序可能无法访问这些文件。ContentResolver.OpenFileDescriptor只能用于读取文件,不能删除文件。

那么从Android Q开始删除曲目的推荐方式是什么?此示例未显示如何从mediastore中删除多个文件,并且mediastore.audio.media的工作方式似乎与mediastore.images.media不同。

共有1个答案

符棋
2023-03-14

在Android10中有两种方法可以做到这一点,这取决于应用程序的AndroidManifest.xml文件中Android:RequestLegacyExternalStorage的值。

选项1:启用了作用域存储(Android:RequestLegacyExternalStorage=“false”)

如果您的应用程序首先添加了内容(使用contentresolver.insert),那么上面的方法(使用contentresolver.delete(mediastore.audio.media.external_content_uri,whereClause,idsArray))应该可以工作。在Android10上,应用程序提交给媒体商店的任何内容都可以由该应用程序自由操作。

对于用户添加的内容,或者属于另一个应用程序的内容,这个过程更加复杂。

若要从媒体存储中删除单个项,请不要将通用媒体存储URI传递给delete(即:mediastore.audio.Media.external_content_uri),而是使用项的特定URI。

context.contentResolver.delete(
    audioContentUri,
    "${MediaStore.Audio.Media._ID} = ?",
    arrayOf(audioContentId)

(我很确定没有必要使用“where”子句,但它对我来说是有意义的:)

选项2:启用遗留存储(Android:RequestLegacyExternalStorage=“true”)

在本例中,只需调用contentresolver.delete(mediastore.audio.media.external_content_uri,whereClause,idsArray)不仅可以从数据库中删除项,还可以删除文件。

应用程序需要持有write_external_storage权限才能工作,但我测试了问题中的代码,并验证了文件是否也被删除了。

因此,对于较旧的API版本,我认为您需要使用ContentResolver.delete并自行取消该文件的链接(或取消该文件的链接并通过MediaCannerConnection提交一个请求,以便重新扫描该文件)。

对于Android10+,ContentResolver.delete将删除索引和内容本身。

 类似资料:
  • 问题内容: 如果文件位于另一个目录中,如何使用PHP从服务器中删除文件? 这是我的页面布局: (此文件将删除我对数据库的所有条目,并且还应删除相关文件) (文件所在的位置。) 我正在使用的功能: 但这总是给我一个错误,该文件不存在。有任何想法吗? 问题答案: 以下应该有帮助 —返回规范化的绝对​​路径名 —告诉文件名是否可写 —删除文件 通过realpath运行文件路径,然后检查返回的路径是否可写

  • 我想将用我的应用程序录制的mp3文件存储到带有MediaStore的音乐文件夹中,以便在Android 10的新“范围存储”中使用。 此方法效果很好,但这些文件使用时间戳命名(例如1576253519449),没有扩展名。 如果我用文件管理器手动添加扩展名,则文件将被正确记录。 如何使用来命名文件? 还有一个问题:只适用于Android 10。如何保持与旧版本的逆转兼容性? 编辑: 为了实现逆转兼

  • 我正在尝试为我的应用程序列出内部存储和外部存储中的所有歌曲作为列表视图。我正在使用下面的代码来获取歌曲 以上代码正在成功地获取外部存储器中的所有歌曲,但未获取内部存储器中存储的歌曲。这在像三星Galaxy S8这样没有外置存储的设备中是一个问题。我还尝试了使用以下uri的光标 这为我获取设备铃声和短信音调,这不是我需要的。 我在StackOverflow中也遇到过类似的问题,但那里的答案并没有为我

  • 问题内容: 我正在创建一个简单的音频编辑工具来修剪和删除音频。我实现了修剪功能,并且工作正常。但是我搜索并尝试实现删除功能,这是我的代码: 我在这里正在创建2个范围。从0-> time1的Range1和从time2-> endOfAudio的Range2。(我想从时间1->时间2中删除) 然后我在2个范围之间创建并集。但是,音频没有任何反应。它的保存与该功能之前的保存完全相同。 问题答案: 返回a

  • 存储过程被创建后,就会一直保存在数据库服务器上,直至被删除。当 MySQL 数据库中存在废弃的存储过程时,我们需要将它从数据库中删除。 MySQL 中使用 DROP PROCEDURE 语句来删除数据库中已经存在的存储过程。语法格式如下: DROP PROCEDURE [ IF EXISTS ] <过程名> 语法说明如下: 过程名:指定要删除的存储过程的名称。 IF EXISTS:指定这个关键字,

  • 问题内容: 我刚刚在android应用程序中编写了一个函数,该函数使用Java中的标准“文件”类删除文件。即: 尽管上面的过程很简单,但我一直想知道通过“ ContentResolver”执行该操作是否有任何好处。任何意见,将不胜感激。 干杯, 杰瑞德 ------------------------------------------编辑------- 这是通过Content Resolver删