在多年以前,我做一款音乐播放器,要把很多.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>