Android 自定义音乐播放器实现

Android自定义音乐播放器

一:首先介绍用了哪些Android的知识点:

1 MediaPlayer工具来播放音乐

2 Handle。因为存在定时任务(歌词切换,动画,歌词进度条变换等)需要由Handle来处理Ui相关内容

3 动态权限申请(该应用程序读取本地歌曲,并且设置音质相关属性)且这两个权限在Android6.0后都需要动态申请

4 手势控制 (左划和右划需要满足一定条件后可以进行切歌)

5 Service服务 (启动Service 绑定Service 前台Service)

6 BroadcastReceiver 广播,Service与Activity,Activity与Activity存在动态交互,需要广播实现

7 基本的重写View能力和Intent交互数据的能力

8 Animation动画 图片旋转 歌词更新


二:实现过程(简要步骤,下面会详细讲解)

1 先编写MusicInfo工具类。因为我们是从手机内存中去读取音乐的相关信息,那么读出的数据该存储到MusicInfo工具类集合中。

2 先申请权限,然后再去手机内存将音乐及其相关的信息读出来 ,用一个ListView容器去装载所有的本地音乐

PS:到了这里基本的音乐信息列表已经有了   这也是我们的主界面(音乐列表界面) 即: 展示音乐/歌曲列表;


3 这时候先不方去实现播放这类的功能,我们先去处理歌词

这里说明一下。一个歌词文件(.Lrc)里面内容格式如下

(张卫健--真英雄)

可以发现他由时间戳和歌词内容两部分组成。有了这个信息后。编写LrcContent工具类,用于记录歌词内容和歌词时间。然后去手机里面寻找歌曲对应的歌词文件,将其编码,读出,装载为LrcContent集合。

4 编写Service类,Service主要用来处理:音乐播放,前台服务。在播放状态改变的时候与播放音乐的Activity进行通信。该Service由主界面启动,后面的Activity绑定即可

5 编写播放音乐的Activity类(MusicPlay)。当我们从主界面(音乐列表界面)点击了一首具体的音乐时,就会调转到该Activity,所有首先,主界面Activity需要传递一些信息给该Activity。

(1) MusicInfo工具类集合。即手机中所有的音乐信息

(2)当前点击的歌曲,传递位置(position)即可

好,现在我们播放音乐的Activity有了所有的音乐信息,还有当前需要播放的歌曲位置。因为需要前台服务,所以我们把音乐播放的控制权交给Service,我们去绑定服务,然后把所有的音乐信息,还有当前需要播放的歌曲位置都传递给Serivce,Service来控制播放音乐。

6 好了,现在我们的程序可以播放音乐了,我们再来一步步完善细节,歌词同步,该功能自定义View实现,最后显现在播放音乐的Activity中。注意Mediaplayer有一个重要属性:

mediaPlayer.getCurrentPosition()。该方法会返回当前播放时间,不过返回的时候时毫秒(重)。

自定义View(LrcView 显示歌词),该View中除了传统的自定义View需要的OnDraw之类的方法外,还需要获取第三步中的LrcContent集合,有了这个我们就有了所有的歌词内容和歌词相应的时间,那么同步如何实现呢?音乐最终该View要显示在播放音乐的Activity(MusicPlay)中,我们去MusicPlay的布局文件申明该View,然后在MusicPlay中编写一个定时器,可以设定每一秒启动一次,定时器发送消息,在Handle中接受消息,处理消息。Handle中我们需要:获取歌曲当前播放时间,根据当前播放时间去LrcContent集合中寻求匹配的歌词。用invalidate()方法,通知自定义View重绘,来同步更新歌词

7 我们的音乐播放器还差一个重要的东西,音乐控制器部分。这部分需要来控制播放上一首,下一首,播放/暂停,音乐进度拖动,音量设置。

该部分不难,所以再这里不详细讲。

三:效果图  因为完整录制的GIF太大,传不上来所以分批处理




四:代码精讲 代码量也不很大,但是全贴出来挨着讲又影响阅读。所以部分节选和重要知识点一并讲解。

PS:源码中含有大量System.out.println("XXXX");语句。个人比较偏爱的一种测试方式。。应该不干扰阅读,忘见谅

1 权限获取,我们要做的第一件事就是去内存读取音乐相关信息,那么我们就需要获得相关的权限,从Android6.0开始部分权限不仅需要在AndroidManifest.xml文件中声明,还需要在运行程序的时候动态获取.这里以读取存储权限为例:

首先在AndroidManifest.xml中定义

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

在Java业务代码中先判断是否已经有权限,有权限就不再申请,没有就申请权限

//首先检查自身是否已经拥有相关权限,拥有则不再重复申请
int check = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) ;
    //没有相关权限
    if (check != PackageManager.PERMISSION_GRANTED)
    {
        //申请权限  STORGE_REQUEST = 1
        ActivityCompat.requestPermissions(this , new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE} ,STORGE_REQUEST);
    }else {
    //已有权限的情况下可以直接初始化程序
    init();
}

当我们申请权限后,去判断用户是否给与了相关权限,如果赋予了就可以做我们的事情了

/*
申请权限处理结果
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     switch (requestCode)
     {
         case STORGE_REQUEST :
             if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
             {
                 //完成程序的初始化
                 init();
                 System.
  • 39
    点赞
  • 127
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值