广告
返回顶部
首页 > 资讯 > 移动开发 >Android音乐播放器开发实战
  • 975
分享到

Android音乐播放器开发实战

实战Android 2022-06-06 13:06:03 975人浏览 八月长安
摘要

本文介绍音乐播放器的音乐播放功能实现。 音乐播放功能最初的形态是根据B站大佬的视频学着做的,现在应该还能搜索到他的视频。当然他只做了一个雏形,印

本文介绍音乐播放器的音乐播放功能实现。

音乐播放功能最初的形态是根据B站大佬的视频学着做的,现在应该还能搜索到他的视频。当然他只做了一个雏形,印象中他只做了一个播放按钮和进度条。然后我在他的基础上逐渐完善各个功能。

感谢这位老哥

一、布局

在这里插入图片描述

播放界面的背景自行挑选,(个人感觉我选的背景还是蛮好看的)。图标都来自 阿里巴巴矢量图标库,内容丰富。

由上至下的控件分别为:

Button控件,用于关闭服务和关闭界面。(这个控件是最后加上的,虽然摆在这里不好看,但是当时没有别的好办法,就暂时放在这里了。) 相对布局,在布局内添加SmartImageView控件,用于加载服务端的歌曲图片(非常好用); 两个TextView控件,第1个用于显示在播歌曲名称,第2个用于显示歌手姓名; 线性布局,在布局内添加SeekBar控件,用于显示歌曲播放进度、用户拖动可以改变进度; 线性布局,在布局内添加5个Button控件,从左到右依次为播放模式、上一首、播放/暂停、下一首、歌曲播放列表。播放模式包括顺序播放、随机播放和单曲循环。 二、功能实现

首先设置两个接口,分别命名为PlayerControl.java和PlayerViewControl.java,用于分离逻辑层和表现层。前者包含的方法有播放上一首play_last()、播放/暂停playOrPause()、播放下一首play_next()、停止播放stopPlay()、设置播放进度seekTo(),并由类PlayerPresenter继承并改写,用于处理程序的内在逻辑;后者包含播放状态的通知onPlayerStateChange()和播放进度的改变onSeekChange(),用于更新UI。

在这里插入图片描述

2.1 获取用户信息

在音乐播放器初始化之前,首先应该获取用户信息数据,根据用户上次关闭播放器之前保留的记录重新展示。在用户登录时,登录程序(暂时还没写,后续更新)将用户信息使用Intent方法进行传递。在本程序中,获取登录账户对应的全部用户信息,并从中解析出用户的账号account、所听歌曲music_id和播放模式pattern。

每个歌曲都有对应的歌曲id,播放时也使用此id。播放模式是int类型,0代表循环播放,1代表随机播放,2代表单曲循环。


Intent intent=getIntent();//获取到Intent对象,包含了用户的整个信息
String user = intent.getStringExtra("result");
JSONObject user_info = (jsONObject) RequestServlet.getJSON(user);
music_id=user_info.optInt("music_id"); //歌曲
account=user_info.optString("account"); //账户
pattern=user_info.optInt("pattern"); //播放模式

上述程序使用的getJSON函数用于将String转换为json,方便提取数据。用于经常用到此方法,因此将其写为了函数。

public static JSONObject getJSON(String json){
    try {
        JSONobj = new JSONObject(json);
    }catch (Exception e){
        e.printStackTrace();
    }
    return JSONobj;
2.2 初始化播放界面

使用findViewById方法绑定布局中的各个控件。

mSeekBar = (SeekBar) this.findViewById(R.id.seek_bar);//进度条
mPlayOrPause = (Button) this.findViewById(R.id.play_or_pause_btn);//播放
mPlay_way = (Button) this.findViewById(R.id.play_way_btn);//播放模式
mPlay_last= (Button) this.findViewById(R.id.play_last_btn);//上一首
mPlay_next = (Button) this.findViewById(R.id.play_next_btn);//下一首
mPlay_menu = (Button) this.findViewById(R.id.play_menu_btn);//歌曲列表
MQuit=(Button) this.findViewById(R.id.quit_btn);//退出
text_view_name = (TextView) this.findViewById(R.id.text_view_name);//歌名
text_view_artist = (TextView) this.findViewById(R.id.text_view_artist);//歌手
siv = (SmartImageView) this.findViewById(R.id.siv_icon);//图片

根据播放模式pattern更改播放界面的播放模式UI

if (pattern==0) {
    mPlay_way.setBackgroundResource(R.drawable.xunhuanbofang);
}else if(pattern==1){
    mPlay_way.setBackgroundResource(R.drawable.suijibofang);
} else if (pattern==2) {
    mPlay_way.setBackgroundResource(R.drawable.danquxunhuan);
}

开启子线程,在服务端获取整个音乐播放列表,并获取歌曲总数song_num,使用Message方法将获取到的音乐列表传递到主线程。

new Thread(){
    public void run(){
        try {
            JSONArray result = RequestServlet.getMusicList();
            song_num=result.length();
            Message msg = new Message();
            msg.what=1;
            msg.obj = result;
            handler1.sendMessage(msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}.start();

获取歌单使用的getMusicList函数如下(实际上这属于客户端与服务端的交互部分的程序,若有不解,待后续给出解释)

//获取歌单
public static JSONArray getMusicList(){
    String path = SELECT_SERVLET+"?table=music&all=Y";
    HttpURLConnection conn;
    JSONArray result;
    try {
        conn = getConn(path);
        int code = conn.getResponseCode();
        if (code == 200){
            InputStream jsonArray = conn.getInputStream();
            String sjsonArray = streamToString(jsonArray);
            result = getJsonArray(sjsonArray);
            conn.disconnect();
            return result;
        }else {
            return null;
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    return null;
}

在主线程中使用Handler方法获取子线程中的音乐列表

private Handler handler1 = new Handler() {
    public void handleMessage(Android.os.Message msg) {
        try {
            if (msg.what == 1) {
                musicList = (JSONArray) msg.obj;
                add_view(0);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

其中add_view函数用于初始化界面信息,由于很多地方应用到了此功能,故将其写为函数,方便调用。

add_view()方法,首先根据music_id在音乐列表中获取用户所听歌曲的全部信息,并从中解析出歌曲的名称、演唱者、歌曲封面存储路径和歌曲所在路径,使用set方法将以上信息全部加载到播放页面,至此,界面初始化完成。然后在该方法中添加一个判断语句,在调用该方法是需要传入一个int型参数,如果该参数等于特定值时(如:1),则执行音乐播放。而初始化时并不需要播放。

public static void add_view(int a) {
    try {
        JSONObject A_music = (JSONObject) musicList.get(music_id); //获取歌曲信息
        String name = A_music.optString("name");
        String author = A_music.optString("author");
        String img = A_music.optString("img");
        address=A_music.optString("address");
     																													siv.setImageUrl(MusiclistActivity.IMG+img,R.mipmap.ic_launcher,R.mipmap.ic_launcher);	//此处在博客中缩进有问题,自行更正																				               
        text_view_name.setText(name);
        text_view_artist.setText(author);
        //如果a=1,则播放
        if (a == 1) {
            if ( mplayerControl != null) {
                mplayerControl.stopPlay();
            }
            mplayerControl.playOrPause();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
2.3 播放/暂停

系统默认播放状态为STOP

对播放按钮设置监听,按钮被点击后,调用逻辑层接口中的playOrPause()方法,创建一个MediaPlayer播放器,指定播放文件为音频。(MediaPlayer类在Android系统中是用于播放音频和视频的,它支持多种格式音频文件,并提供了非常全面的控制方法,从而使播放音频的工作变得十分简单。)


private void initPlayer() {
    if (mMediaPlayer == null) {
        mMediaPlayer=new MediaPlayer();
        //指定参数为音频文件
        mMediaPlayer.setAudiOStreamType(AudioManager.STREAM_MUSIC);
    }
}

MediaPlayer播放器按照初始化中解析出的歌曲所在路径获取歌曲文件,使用start方法开始播放音乐,同时修改播放状态为PLAY,开始计时。

if (mCurrentState == PLAY_STATE_STOP) {
    //创建播放器
    initPlayer();
    try {
        //指定播放路径
        mMediaPlayer.setDataSource(MainActivity.ADDRESS + MainActivity.address);
        //准备播放
        mMediaPlayer.prepareAsync();
        //播放
        mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mMediaPlayer.start();
            }
        });
        mCurrentState = PLAY_STATE_PLAY;
        startTimer();

播放状态更新后,通知表现层接口的onPlayerStateChange()方法,进行UI更新。

private PlayerViewControl mPlayerViewControl=new PlayerViewControl() {
    @Override
    public void onPlayerStateChange(int state) {
        //我们要根据播放状态来修改UI
        switch (state) {
            case PLAY_STATE_PLAY:
                //播放中的话,我们要修改按钮显示为暂停
                mPlayOrPause.setBackgroundResource(R.drawable.bofangb);
                break;
            case PLAY_STATE_PAUSE:
            case PLAY_STATE_STOP:
                //反之,修改为播放
                mPlayOrPause.setBackgroundResource(R.drawable.bofang);
                break;
        }
    }

再次点击播放按钮,音乐暂停播放,更改状态为PAUSE,停止计时,并更新UI。

else if (mCurrentState == PLAY_STATE_PLAY) {
    //如果当前的状态为播放,那么就暂停
    if (mMediaPlayer != null) {
        mMediaPlayer.pause();
        mCurrentState = PLAY_STATE_PAUSE;
        stopTimer();
    }
} else if (mCurrentState == PLAY_STATE_PAUSE) {
    //如果当前的状态为暂停,那么继续播放
    if (mMediaPlayer != null) {
        mMediaPlayer.start();
        mCurrentState = PLAY_STATE_PLAY;
        startTimer();
    }
}
2.4 进度条更新

歌曲播放时,系统创建一个Timer()方法,设置该方法每隔500ms访问一次run()方法。run()方法获取歌曲播放进度,将其转化为百分比,当歌曲进度小于100%时,通知表现层进行进度条更新。

public void run() {
    //获取当前的播放进度
    if (mMediaPlayer != null && mViewController!=null) {
        int currentPosition = mMediaPlayer.getCurrentPosition();
        //记录百分比
        int curPosition=(int)(currentPosition*1.0f/mMediaPlayer.getDuration()*100);
        if(curPosition<=100) {
            mViewController.onSeekChange(curPosition);
        }
    }
}

表现层获取歌曲播放百分比,使用setProgress进行进度条更新,当歌曲播放进度为100%时,执行播放下一首操作。

public void onSeekChange(final int seek) {
    //改变播放进度,有一个条件:当用户的手触摸到进度条的时候,就不更新。
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (!isUserTouchProgressBar) {
                mSeekBar.setProgress(seek);
                if(seek==100) {
                    mplayerControl.play_next();
                }
            }
        }
    });
}
2.5 拖拽进度条改变播放进度 对进度条改变设置监听。 用户在歌曲播放时拖动进度条,停止拖动时,获取进度条当前值所占百分比,传入逻辑层的seekTo()方法; 逻辑层将传入的值转化为歌曲播放时间,使用MediaPlayer的seekTo()方法改变歌曲播放进度。
@Override
//设置播放进度
public void seekTo(int seek) {
    //0~100之间
    //需要做一个转换,得到的seek其实是一个百分比
    if (mMediaPlayer != null) {
        //getDuration()获取音频时长
        int tarSeek=(int)(seek*1f/100*mMediaPlayer.getDuration());
        mMediaPlayer.seekTo(tarSeek);
    }
}
2.6 更改播放模式 将播放模式pattern声明为int型公共变量,供所有类调用。 对播放模式按钮设置监听。 对播放模式进行求余操作,确保值不会“溢出”。 用户点击一次按钮,更改一次pattern值,并根据pattern值更改UI。
mPlay_way.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {
        if( mplayerControl != null) {
            pattern=(pattern+1) % 3;
            if (pattern==0) {
                mPlay_way.setBackgroundResource(R.drawable.xunhuanbofang);
            }else if(pattern==1){
                mPlay_way.setBackgroundResource(R.drawable.suijibofang);
            } else if (pattern==2) {
                mPlay_way.setBackgroundResource(R.drawable.danquxunhuan);
            }
        }
    }
}
2.7 播放上一首 对播放上一首按钮设置监听。 用户点击按钮后,调用逻辑层的play_last()方法。 根据播放模式的不同,在不同条件语句下对music_id进行减法操作。 调用add_view()方法,传入参数1,播放新歌曲。
public void play_last() {
    // 顺序播放
    if (MainActivity.pattern == 0) {
        if (MainActivity.music_id == 0) {
            MainActivity.music_id = MainActivity.song_num;
            MainActivity.add_view(1);
        } else {
            MainActivity.music_id = MainActivity.music_id - 1;
            MainActivity.add_view(1);
        }
    }
    //随机播放
    else if (MainActivity.pattern == 1) {
        MainActivity.music_id=(MainActivity.music_id+(int)(1+Math.random()*(20-1+1))) % MainActivity.song_num ;
        MainActivity.add_view(1);
    }
    //单曲循环
    else if(MainActivity.pattern==2){
        MainActivity.add_view(1);
    }
}
2.8 播放下一首 与播放上一首功能类似,对music_id进行加法操作。 2.9 停止播放 用于切换歌曲,在切换歌曲前,应该停止播放当前歌曲。 更改播放状态。 停止计时。 释放MediaPlayer的资源。(因为播放新的歌曲会创建新的MediaPlayer)
@Override
public void stopPlay() {
    if (mMediaPlayer != null ) {
        mMediaPlayer.stop();
        mCurrentState= PLAY_STATE_STOP;
        stopTimer();
        //更新播放状态
        if (mViewController != null) {
            mViewController.onPlayerStateChange(mCurrentState);
        }
        mMediaPlayer.release();//释放资源
        mMediaPlayer=null;
    }
}
2.10 打开音乐列表 对按钮设置监听。 按钮被点击,打开音乐列表。
mPlay_menu.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if ( mplayerControl != null) {
            Intent intent = new Intent(MainActivity.this,MusiclistActivity.class);
            startActivity(intent);
        }
    }
}
2.11 Service(服务) 服务可以长期运行在后台,没有用户界面,可以用来播放歌曲; 关闭按钮被点击时,服务才被销毁。 2.12 onKeyDown()方法 用于监听用户是否点击手机的返回键 该方法将home界面当做一个Activity,再次打开软件,不会重启软件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent home = new Intent(Intent.ACTION_MAIN);
        home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        home.addCateGory(Intent.CATEGORY_HOME);
        startActivity(home);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
2.13 关闭按钮 设置监听。 按钮被点击时,调用stopPlay()方法,停止播放歌曲,释放掉MediaPlayer资源。 开启子线程,保存用户当前所听歌曲ID和播放模式到服务端对应账户中。
private void write() {
    new Thread() {
        public void run () {
            try {
                JSONObject result = RequestServlet.SavePlayerInfORMation(account, music_id, pattern, 0);
                Message msg = new Message();
                msg.what = 1;
                msg.obj = result;
                handler2.sendMessage(msg);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }.start();
}
关闭服务。 关闭界面。
private Handler handler2 = new Handler() {
    public void handleMessage(android.os.Message msg) {
        try {
            if (msg.what == 1) {
                JSONObject result = (JSONObject) msg.obj;
                stop();
                MainActivity.this.finish();
                Toast.makeText(MainActivity.this, "已退出", Toast.LENGTH_SHORT).show();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
};

至此,音乐播放界面的功能已基本实现。


作者:sjcup


--结束END--

本文标题: Android音乐播放器开发实战

本文链接: https://www.lsjlt.com/news/29311.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android音乐播放器开发实战
    本文介绍音乐播放器的音乐播放功能实现。 音乐播放功能最初的形态是根据B站大佬的视频学着做的,现在应该还能搜索到他的视频。当然他只做了一个雏形,印...
    99+
    2022-06-06
    实战 Android
  • Android开发简易音乐播放器
    这里介绍一个简易的音乐播放器,供大家参考,具体内容如下 效果图如下: 但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死,但,操作却十分简单,方便理解! 这...
    99+
    2022-06-06
    音乐 android开发 Android
  • Android编程开发音乐播放器实例
    本文实例讲述了Android编程开发音乐播放器,分享给大家供大家参考,具体如下: 音乐播放器中综合了以下内容: SeekBar、ListView、广播接收者(以代码的形式注册R...
    99+
    2022-06-06
    音乐 Android
  • Android 音乐播放器的开发实例详解
       本文将引导大家做一个音乐播放器,在做这个Android开发实例的过程中,能够帮助大家进一步熟悉和掌握学过的ListView和其他一些组件。为了有更好的...
    99+
    2022-06-06
    音乐 Android
  • 利用Android开发一个音乐播放器
    本篇文章为大家展示了利用Android开发一个音乐播放器,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。读取本地音乐文件源代码:import android.media.MediaPlayer;imp...
    99+
    2023-05-31
    android roi
  • Android 开源在线音乐播放器
    封面图:  简介 波尼音乐是一款开源Android在线音乐播放器。 播放本地音乐与在线音乐 在线音乐排行榜,如热歌榜、新歌榜等 高仿云音乐的黑胶...
    99+
    2022-06-06
    开源 在线音乐 音乐 Android
  • Android Studio开发(三)使用BroadcastReceiver实现音乐播放器
    Android Studio开发(三)使用BroadcastReceiver实现音乐播放器Android Studio开发(三)使用Broadc...
    99+
    2022-06-06
    Android Studio studio 音乐 Android
  • Android Studio 实现音乐播放器
    目录 一、引言 视频效果展示: 图片效果展示: .启动页效果 2.登录页效果 3.注册页效果 4.歌曲列表页效果 5.播放页效果  二、详细设计 1.登陆注册功能 2.音乐列表页面 2.音乐播放功能 一、引言         Andr...
    99+
    2023-09-29
    android studio android ide
  • Android音乐播放器如何实现
    这篇“Android音乐播放器如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android音乐播放器如何实现”文章吧...
    99+
    2023-07-04
  • android实现简单音乐播放器
    本文实例为大家分享了android音乐播放器的具体代码,供大家参考,具体内容如下 话不多说先上效果 前言 写这个音乐播放器实在是迫不得已。因为我们Andoird课程要求写一个...
    99+
    2022-06-06
    音乐 Android
  • Android开发中怎么实现一个音乐播放器功能
    Android开发中怎么实现一个音乐播放器功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。具体实现首先是布局文件中添加了如下代码,这些代码就是实现控制台的,给整体设置了一...
    99+
    2023-05-31
    android roi
  • Android开发中如何实现一个音乐播放器功能
    Android开发中如何实现一个音乐播放器功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。需求1:将内存卡中的MP3音乐读取出来并显示到列表当中从数据库中查询所有音乐数据...
    99+
    2023-05-31
    android 音乐播放器 roi
  • Android简单音乐播放实例
    Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了。Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在...
    99+
    2022-06-06
    音乐 Android
  • Android实现音乐视频播放
    本文实例为大家分享了Android实现音乐视频播放的具体代码,供大家参考,具体内容如下 步骤 1、新建一个安卓项目,再加一个assets包 2、在 assets中加入一段音频 3...
    99+
    2022-11-12
  • Android仿音乐播放器功能
    本文实例为大家分享了Android仿音乐播放器功能的具体代码,供大家参考,具体内容如下 读取本地音乐文件 源代码: import android.media.MediaPla...
    99+
    2022-06-06
    音乐 Android
  • Android studio 音乐播放器提交
    这里要完成音乐播放,我们需要使用到Broadcast实现模式,也就是我们所说的广播 先展示一下项目成品哈: 在编写main...
    99+
    2022-06-06
    Android Studio studio 音乐 Android
  • Android实现简单的音乐播放器
    本文实例为大家分享了Android实现简单音乐播放器的具体代码,供大家参考,具体内容如下 1.制作一个简易的音乐播放器 使用软件:Android studio + jdk1.8 + ...
    99+
    2022-11-13
  • Android实现音乐播放器锁屏页
    本文实例为大家分享了Android音乐播放器锁屏页的具体代码,供大家参考,具体内容如下 首页我们先看一下效果图 下边来说一下实现逻辑,其主要思路就是新建一个activity使...
    99+
    2022-06-06
    锁屏 音乐 Android
  • Android实现简易的音乐播放器
    本文实例为大家分享了Android实现简易的音乐播放器,供大家参考,具体内容如下 功能介绍 本次实验实现的是使用Andriod Studio开发一个简易的音乐播放器,所包含的功能有音...
    99+
    2022-11-12
  • Android Studio如何实现音乐播放器
    这篇文章主要介绍了Android Studio如何实现音乐播放器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、项目概述1、需求分析综合运用UI界面设计、数据存储...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作