在多年以前,我做一款音乐播放器,要把很多.mp3文件,放置在自己新建的文件夹里面,然后去读取这个新建的文件夹里面的音乐列表,现在想想是多么的无知;
因为只要往手机里面放入.mp3文件,系统会自动检测,并把检测到的结果(.mp3的详细信息)存入数据库,并内容提供者应用,对外暴露音乐相关的所有信息
MediaProvider多媒体内容提供者应用:
MediaProvider内容提供者应用的目录在:
![]()
MediaProvider对外暴露的领域:
1.对外暴漏【(内部存储的:手机自身存储控件的),(外部存储的:sdcard)】的音频相关(.mp3音乐)
2.对外暴漏【(内部存储的:手机自身存储控件的),(外部存储的:sdcard)】的视频相关
3.对外暴漏【(内部存储的:手机自身存储控件的),(外部存储的:sdcard)】的图片相关
MediaProvider对外暴露的内容提供者应用 在Android文件系统的目录:
/data/data/com.android.providers.media

阅读MediaProvider内容提供者应用 /data/data/com.android.providers.media 的数据库:

把external.db 导出去,然后打开,audio_meta是所有音频表的详细信息

把external.db 导出去,然后打开,video是所有视频表的详细信息

把external.db 导出去,然后打开,images是所有图片表的详细信息

MediaProvider对外暴露(音频,视频,图片)相关信息:

上一篇博客,Android-读取操作系统通话记录并/拨打电话/发送短信/复制号码到拨号盘,中讲解到通话记录通常是有常量的,真实开发中,必须要用常量,才靠谱,万一字段变来怎么办!
所以要通过ContentProvider去访问MediaProvider的音频/视频/图片/等 的时候,必须全部用常量来操作:
Android API 已经区分来,音频,视频,图片相关的处理:


通过 Media.常量获取外置存储的Uri,播放第一首音乐🎵
/** * 通过 Media.常量获取外置存储的Uri,播放第一首音乐🎵 */ public void playMusic(View view) { /** * 访问多媒体(音频/视频/图片)用常量 */ /** * 内置的Uri 访问手机本身内置空间的(音频/视频/图片) */ Uri internalContentUriAudio = MediaStore.Audio.Media.INTERNAL_CONTENT_URI; // 内置音频 Uri internalContentUriVideo = MediaStore.Video.Media.INTERNAL_CONTENT_URI; // 内置视频 Uri internalContentUriImage = MediaStore.Images.Media.INTERNAL_CONTENT_URI; //内置图片 /** * 外置的Uri 访问Sdcard外部挂载卡空间的(音频/视频/图片) */ Uri externalContentUriAudio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; // 外置音频 Uri externalContentUriVideo = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; // 外置视频 Uri externalContentUriImage = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; // 外置图片 /** * 有很多很多字段,只获取某些字段 */ String[] projections = new String[]{ MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM, // 专辑 MediaStore.Audio.Media.DISPLAY_NAME, // 显示的名称 MediaStore.Audio.Media.DURATION, // 音频时长 MediaStore.Audio.Media.ARTIST, // 歌手名称 MediaStore.Audio.Media.DATA // 路径 }; Cursor cursor = getContentResolver().query(externalContentUriAudio, projections, null, null, null); if (cursor.moveToFirst()) { String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); Log.d("ccc", "data:" + data); /** * 播放某一首音乐 ,播放外置音频文件 */ try { MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.reset(); /** * 我就想播放第一首歌曲,所以需要把ID进行写入Uri操作 */ /*Log.d("ccc", externalContentUriAudio.toString()); Uri map3Music1 = ContentUris.withAppendedId(externalContentUriAudio, 1); // 播放第一首歌曲 mediaPlayer.setDataSource(this, map3Music1);*/ mediaPlayer.setDataSource(data); mediaPlayer.prepare(); mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); } } }
需要在AndroidManifest.xml配置权限:
<!-- 读外置存储的权限 访问操作系统多媒体提供者应用,需要加入的权限 <path-permission android:pathPrefix="/external/" android:readPermission="android.permission.READ_EXTERNAL_STORAGE" android:writePermission="android.permission.WRITE_EXTERNAL_STORAGE" /> --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
为什么要在AndroidManifest.xml配置权限 ????????
因为在 android操作系统源码/packages/providers/MediaProvider/AndroidManifest.xml <provider节点 指定需要权限
![]()
<path-permission
android:pathPrefix="/external/"
android:readPermission="android.permission.READ_EXTERNAL_STORAGE"
android:writePermission="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider android:name="MediaProvider" android:authorities="media" android:multiprocess="false" android:exported="true"> <grant-uri-permission android:pathPrefix="/external/" /> <path-permission android:pathPrefix="/external/" android:readPermission="android.permission.READ_EXTERNAL_STORAGE" android:writePermission="android.permission.WRITE_EXTERNAL_STORAGE" /> </provider>
浙公网安备 33010602011771号