MediaPlayer之音乐播放器完整解析

本文详细介绍了如何使用MediaPlayer构建一个音乐播放器,包括从本地SD卡搜索音乐,使用AIDL进行服务与Activity交互,SeekBar与音量同步,自定义TextView绘制歌词,解析本地歌词,以及创建自定义通知栏等功能。

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

MediaPlayer 是一款音乐播放器也是一款视频吧哦,这篇先介绍一个音乐播放器吧!

先看一下做好的效果吧!
这里写图片描述

这次介绍的功能点:
1、本地Sd卡中搜索音乐,并保存在List中
2、服务与Activity交互,可以用AIDL 、Binder,这次我们采用AIDL
3、SeekBar与音量关联同步 并修改时间
4、自定义TextView画歌词 并实现缓缓移动效果,并实现歌词与进度条同步
5、解析本地歌词
6、自定义通知栏

OK。先做一下准备工作。

首先我们来看一下MadiaPlayer的工作原理:
这里写图片描述

介绍之前大家先看一下这个图,然后看我的项目以后,回过头来再看一遍,会清晰好多。

在本地SD卡中查找音乐并且保存在List中:代码如下

    /**
     * 从本地sdcard获取数据
     * 1、遍历sdcard,通过后缀名获取(效率比较慢)
     * 2、通过内容提供者数据库中获取(Android系统内部有一个扫描器 ———— “媒体扫描器”,当手机开机完成后,或者sdcard插好后,
     *    系媒体扫描器会发送一个广播开始工作,开始扫描sdcard,然后把数据存到数据库中,从而提供给第三方使用)
     *   todo 内容提供者:解决应用与应用共享数据,通过内容提供者暴露出来使用。
     * 3、6.0动态权限
     */
    public void getDataFromLocal() {
        // 新建一个线程,比较耗时
        new Thread(){
            public void run(){
                // 获取内容提供者
                ContentResolver contentResolver = getContext().getContentResolver();
                Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                String[] obj = {
                        MediaStore.Audio.Media.DISPLAY_NAME,//音频文件在sdcard的名称
                        MediaStore.Audio.Media.DURATION,//音频总时长
                        MediaStore.Audio.Media.SIZE,//音频的文件大小
                        MediaStore.Audio.Media.DATA,//音频的绝对地址(音频的播放地址)
                        MediaStore.Audio.Media.ARTIST,//歌曲的演唱者
                };
                // 查询方法。 参数1:uri.  参数2: 查询的指令
                Cursor cursor = contentResolver.query(uri, obj, null, null, null);
                if(cursor != null) {
                    while(cursor.moveToNext()) {
                        MediaItem mediaItem = new MediaItem();
                        mList.add(mediaItem);
                        // TODO: 2018/1/4  查询的0 1等位置是根据contentResolver.query()方法传入的obj参数获取的。
                        //音频的名称
                        String name = cursor.getString(0);
                        mediaItem.setName(name);
                        //音频的时长
                        long duration = cursor.getLong(1);
                        mediaItem.setDuration(duration);
                        //音频的文件大小
                        long size = cursor.getLong(2);
                        mediaItem.setSize(size);
                        //音频的播放地址
                        String data = cursor.getString(3);
                        mediaItem.setData(data);
                        //艺术家
                        String artist = cursor.getString(4);
                        mediaItem.setArtist(artist);
                    }
                    cursor.close();
                }
                // 更新UI
                handler.sendEmptyMessage(MAG_HANDLER);
            }
        }.start();
    }

    /**
     * 6.0动态获取sd卡权限
     */
    public  boolean isGrantExternalRW(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && activity.checkSelfPermission(
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            activity.requestPermissions(new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            }, 1);
            return false;
        }
        return true;
    }

创建AIDL让服务与Activity通信:
1、创建服务
2、在清单文件中添加:

        <service android:name=".serveice.MusicPlayerService">
            <intent-filter>
                <action android:name="com.atguigu.mobileplayer_OPENAUDIO" />
            </intent-filter>
        </service>

3、在工程目录下,选中main 然后右键创建AIDL文件,此文件就是声明方法,暴露的方法让Activity调用,从而Aidl在调用服务中的方法。AIDL可以说是一个代理类。完成服务与页面的交互:
我把所有的方法都写出来了,方便后期大家查询

interface IMusicPlayerService {
      /**
        * 根据位置打开对应的音频文件
        * @param position
        */
        void openAudio(int position);

       /**
        * 播放音乐
        */
        void start();

       /**
        * 播暂停音乐
        */
        void pause();

       /**
        * 停止
        */
        void stop();

       /**
        * 得到当前的播放进度
        * @return
        */
        int getCurrentPosition();

       /**
        * 得到当前音频的总时长
        * @return
        */
        int getDuration();

       /**
        * 得到艺术家
        * @return
        */
        String getArtist();

       /**
        * 得到歌曲名字
        * @return
        */
        String getName();

       /**
        * 得到歌曲播放的路径
        * @return
        */
        String getAudioPath();

       /**
        * 播放下一个视频
        */
        void next();

       /**
        * 播放上一个视频
        */
        void pre();

       /**
        * 设置播放模式
        * @param playmode
        */
        void setPlayMode(int playmode);

       /**
        * 得到播放模式
        * @return
        */
        int getPlayMode();

        /**
        * 是否正在播放
        */
         boolean isPlaying();

         /**
          拖动音频
         */
         void seekTo(int position);

         int getAudioSessionId();
         }

4、在服务中创建AIDL,然后AIDL调用服务的方法。如下:
我这里只是粘贴了一部分方法,全部的方法跟AIDL声明的方法一样。 最重要的不要忘记在服务中把stub返回去。 这样通过AIDL一个代理类就可以了

    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }
  /**
     * 创建AIDL 服务代理类, 通过代理类与服务交互
     */
    private IMusicPlayerService.Stub stub = new IMusicPlayerService.Stub(){
        /** 创建服务*/
        MusicPlayerService service = MusicPlayerService.this;

        @Override
       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值