通过MediaStore来获取Audio信息

本文介绍了如何在OPhone系统中利用MediaStore查询SD卡和手机内存上的音频文件信息,包括歌曲、歌手、专辑和播放列表。通过ContentResolver查询接口,开发者可以方便地获取音乐的详细数据,并组合查询条件来定位特定的媒体信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OPhone系统提供了 MediaScanner,MediaProvider,MediaStore等接口,并且提供了一套数据库表格,通过Content Provider的方式提供给用户。当手机开机或者有SD卡插拔等事件发生时,系统将会自动扫描SD卡和手机内存上的媒体文件,如 audio,video,图片等,将相应的信息放到定义好的数据库表格中。在这个程序中,我们不需要关心如何去扫描手机中的文件,只要了解如何查询和使用 这些信息就可以了。
  
MediaStore中定义了一系列的数据表格,通过ContentResolver提供的查询接口,我们可以得到各种需要的信息。下面我们重点介绍如何管理SD卡上的音乐文件信息。

Cursor cursor = context.getContentResolver.query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

Uri:指明要查询的数据库名称加上表的名称,从MediaStore中我们可以找到相应信息的参数,具体请参考开发文档。
Projection: 指定查询数据库表中的哪几列,返回的游标中将包括相应的信息。Null则返回所有信息。
selection: 指定查询条件
selectionArgs:参数selection里有 ?这个符号是,这里可以以实际值代替这个问号。如果selection这个没有?的话,那么这个String数组可以为null。
SortOrder:指定查询结果的排列顺序

1.查询所有歌曲:

Cursor cursor = query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,  null ,  
                null ,  null , MediaStore.Audio.Media.DEFAULT_SORT_ORDER); 
if(cursor == null){return;}

if(cursor.moveToFirst(){
do{

//MediaStore.Audio.Media.IS_MUSIC: 是否是音乐文件,返回0即为音乐媒体文件
Int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));

//MediaStore.Audio.Media._ID:歌曲ID  
Int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));  

//MediaStore.Audio.Media.TITLE:歌曲的名称  
String tilte = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));  

//MediaStore.Audio
<think>好的,我现在需要解决用户关于MediaStore.Audio.Media.DATE_ADDED返回当前日期的问题。用户想知道为什么这个字段会返回当前日期,以及如何解决这个问题。首先,我得回忆一下MediaStore的相关知识,特别是DATE_ADDED字段的作用。 根据引用内容,MediaStore用于管理多媒体文件的信息,比如歌曲、视频等。DATE_ADDED这个字段通常记录的是文件被添加到媒体库的时间,而不是文件本身的创建或修改时间。用户的问题可能出现在他们期望获取文件的实际日期,但系统返回了当前日期,这可能是因为文件被重新扫描或更新,导致DATE_ADDED被更新为当前时间。 接下来,我需要考虑可能的原因。根据引用[1],更新媒体库中的信息时,某些字段会被修改。例如,当用户设置铃声或通知音时,相关字段会被置为1。类似地,当媒体库重新扫描文件时,可能会更新DATE_ADDED为当前时间,尤其是在文件被重新插入或媒体库被强制刷新时。此外,如果用户通过ContentResolver插入数据(如引用[2]中提到的),可能会影响DATE_ADDED的值,因为插入操作会记录当前时间。 解决方案方面,用户可能需要获取文件的实际日期,而不是媒体库中的添加时间。这时候应该建议使用其他字段,比如DATE_MODIFIED或DATE_TAKEN,或者直接从文件的元数据获取。例如,引用[2]提到MediaStore.Audio.Media.DATA字段存储文件路径,可以通过该路径访问文件的最后修改时间。使用File对象的lastModified()方法可以获取更准确的时间。 此外,引用[4]提到了使用AsyncTask来处理后台操作,比如扫描文件。如果在插入或更新媒体库后立即查询DATE_ADDED,可能因为媒体库尚未完成更新而导致获取到错误的时间。因此,建议在媒体库更新完成后再进行查询,或者使用ContentObserver监听数据变化,确保获取到正确的值。 总结可能的原因:1. 媒体库更新导致DATE_ADDED被覆盖;2. 插入数据时自动记录当前时间;3. 文件被重新扫描或移动导致时间更新。解决方案包括使用其他字段、直接读取文件属性、处理媒体库更新时机以及使用ContentObserver。 最后,需要验证这些解决方案是否可行。例如,通过代码示例展示如何获取DATE_MODIFIED或使用File对象,提醒用户注意权限问题,以及处理媒体库刷新的异步操作。同时,要确保回答结构清晰,分点说明原因和解决方法,并引用提供的参考资料来支持结论。</think>### 原因分析 `MediaStore.Audio.Media.DATE_ADDED`返回当前日期的核心原因是**媒体库的更新机制**。该字段记录的是文件被添加到媒体库的时间戳,而非文件本身的创建时间或最后修改时间[^1][^3]。以下是具体原因: 1. **媒体库重新扫描** 当系统触发媒体扫描(如插入存储设备、重启或手动刷新),若文件元数据未被正确缓存,系统可能将`DATE_ADDED`重置为当前时间[^3]。 2. **内容提供器写入操作** 通过`ContentResolver`插入或更新数据时,若未显式指定`DATE_ADDED`的值,系统会默认使用当前时间戳填充该字段[^2][^4]。 3. **文件路径变化** 如果文件被移动或重命名后重新扫描,`MediaStore`可能将其视为新条目,导致`DATE_ADDED`更新为当前时间[^1]。 --- ### 解决方案 #### 方法一:改用`DATE_MODIFIED`字段 若需获取文件的实际修改时间,建议使用`MediaStore.Audio.Media.DATE_MODIFIED`字段: ```java Cursor cursor = getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Audio.Media.DATE_MODIFIED}, null, null, null ); ``` 该字段直接关联文件系统的最后修改时间戳[^2]。 #### 方法二:通过文件路径获取数据 结合`MediaStore.Audio.Media.DATA`字段获取文件路径,再通过`File`类读取元数据: ```java String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); File file = new File(path); long lastModified = file.lastModified(); // 单位:毫秒 ``` 需注意: - 需要`READ_EXTERNAL_STORAGE`权限 - 文件被删除时会返回`0` #### 方法三:强制同步媒体库 通过`MediaScannerConnection`主动触发扫描并等待完成: ```java MediaScannerConnection.scanFile(context, new String[]{filePath}, null, new MediaScannerConnection.OnScanCompletedListener() { @Override public void onScanCompleted(String path, Uri uri) { // 扫描完成后查询DATE_ADDED } }); ``` #### 方法四:使用`ContentObserver`监听变更 ```java ContentObserver observer = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { // 媒体库更新后重新查询数据 } }; getContentResolver().registerContentObserver( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, observer ); ``` --- ### 关键差异对比表 | 字段/方法 | 数据来源 | 实时性 | 可靠性 | 适用场景 | |-------------------------|---------------|------------|------------|-----------------------| | `DATE_ADDED` | 媒体库元数据 | 可能滞后 | 低 | 记录添加入库时间 | | `DATE_MODIFIED` | 文件系统 | 实时 | 高 | 获取实际修改时间 | | `File.lastModified()` | 文件系统 | 实时 | 最高 | 需要精确控制时 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值