一、功能要求
在基于存储卡音乐播放器V0.2基础上,增加功能:

添加一个音乐播放列表(显示歌名)
– 单击某一首音乐就立刻播放,播放进度清零,显示当前音乐的播放时长。
添加一个【上一首】与【下一首】按钮----完成
– 当前音乐为第一首时,单击【上一首】按钮,切换到最后一首音乐。----完成
– 当前音乐为最后一首时,单击【下一首】按钮,切换到第一首音乐。----完成
– 当某一首音乐播放完毕后,会自动切换到下一首音乐播放。----完成

二、运行效果

实现步骤
将图片素材拷贝到drawable目录与mipmap目录

上一首按钮背景图片选择器 - previous_button_selector.xml

下一首按钮背景图片选择器 - next_button_selector.xml

主布局资源文件activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/background"android:orientation="vertical"android:padding="20dp"tools:context=".ui.MainActivity"><ListViewandroid:id="@+id/lvMusicName"android:layout_width="match_parent"android:layout_height="0dp"android:layout_marginBottom="16dp"android:layout_weight="8" /><TextViewandroid:id="@+id/tvMusicName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="0.5"android:textColor="#0000ff"android:textSize="20sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:layout_marginBottom="10dp"android:layout_weight="0.5"android:gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/tvCurrentPosition"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textColor="#ff0000" /><ProgressBarandroid:id="@+id/pbMusicProgress"style="?android:attr/progressBarStyleHorizontal"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="6" /><TextViewandroid:id="@+id/tvDuration"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textColor="#ff00ff" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="0.5"android:gravity="center"android:orientation="horizontal"><Buttonandroid:id="@+id/btnPrevious"android:layout_width="60dp"android:layout_height="50dp"android:background="@drawable/previous_button_selector"android:onClick="doPrevious" /><Buttonandroid:id="@+id/btnPlayOrPause"android:layout_width="60dp"android:layout_height="50dp"android:background="@drawable/play_button_selector"android:onClick="doPlayOrPause" /><Buttonandroid:id="@+id/btnNext"android:layout_width="60dp"android:layout_height="50dp"android:background="@drawable/next_button_selector"android:onClick="doNext" /></LinearLayout>
</LinearLayout>
主界面类 - MainActivity```cpp
package net.yq.sdcardmusicplayerv03.ui;import android.Manifest;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;import net.yq.sdcardmusicplayerv03.R;
import net.yq.sdcardmusicplayerv03.adapter.MusicAdapter;
import net.yq.sdcardmusicplayerv03.entity.Music;
import net.yq.sdcardmusicplayerv03.util.CommonUtils;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private MediaPlayer mp; // 媒体播放器private File musicDir; // 音乐存放目录private String musicName; // 音乐文件名private TextView tvMusicName; // 音乐名标签private Button btnPlayOrPause; // 播放|暂停按钮private int currentPosition; // 音乐当前播放位置private TextView tvCurrentPosition; // 显示当前播放位置的标签private TextView tvDuration; // 显示音乐播放时长的标签private ProgressBar pbMusicProgress; // 音乐播放进度条private Thread thread; // 线程private Handler handler; // 消息处理器private boolean isRunning; // 线程循环控制变量private List<Music> musicList;//音乐数据源private ListView lvMusicName;//音乐(数据源)private MusicAdapter adapter;//适配器private int musicIndex;//索引@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取控件实例lvMusicName = findViewById(R.id.lvMusicName);btnPlayOrPause = findViewById(R.id.btnPlayOrPause);tvMusicName = findViewById(R.id.tvMusicName);tvCurrentPosition = findViewById(R.id.tvCurrentPosition);tvDuration = findViewById(R.id.tvDuration);pbMusicProgress = findViewById(R.id.pbMusicProgress);// 定义存储读写权限数组String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};// 检查是否有读权限int permission = ActivityCompat.checkSelfPermission(this, PERMISSIONS_STORAGE[0]);// 如果没有授权,那么就请求读权限if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 0);}//获取音乐列表musicList = getMusicLists();//判断列表是否为空if (musicList != null) {//创建适配器adapter = new MusicAdapter(this, musicList);//设置适配器lvMusicName.setAdapter(adapter);//获取音乐名标签内容(默认为第一首)musicName = musicList.get(0).getMusicName();//设置播放音乐名tvMusicName.setText("No." + (musicIndex + 1) + " " + musicName.substring(0, musicName.lastIndexOf(".")));//初始化播放器mp = new MediaPlayer();try {//设置播放源mp.setDataSource(musicDir.getAbsolutePath() + "/" + musicName);// 缓冲播放源(从存储卡加载到内存)mp.prepare();//设置当前播放位置标签tvCurrentPosition.setText(CommonUtils.getFormatTime(mp.getCurrentPosition()));//设置音乐播放时长标签tvDuration.setText(CommonUtils.getFormatTime(mp.getDuration()));//获取进度条最大值pbMusicProgress.setMax(mp.getDuration());} catch (IOException e) {e.printStackTrace();}//设置循环变量为真isRunning = true;//创建子线程,定时发送消息thread = new Thread(new Runnable() {@Overridepublic void run() {while (isRunning) {handler.sendEmptyMessage(0x001);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});//启动子线程thread.start();//创建消息处理器,接受子线程发送的消息handler = new Handler() {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);if (msg.what == 0x001) {if (mp.isPlaying()) {currentPosition = mp.getCurrentPosition();pbMusicProgress.setProgress(currentPosition);tvCurrentPosition.setText(CommonUtils.getFormatTime(currentPosition));}}}};//设置监听器lvMusicName.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {//获取索引musicIndex = position;//进度归零currentPosition = 0;try {play();} catch (IOException e) {e.printStackTrace();}}});mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mediaPlayer) {//当前音乐播放完毕,切换下一首try {//下一曲nextMusic();} catch (IOException e) {e.printStackTrace();}}});} else {Toast.makeText(this, "存储卡Music目录里没有音乐文件!", Toast.LENGTH_SHORT).show();}}/*** 获取音乐列表** @return*/public List<Music> getMusicLists() {//声明音乐列表对象List<Music> musicList = null;//获取音乐存放目录musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);//定义数组名String[] musicNames = musicDir.list();//判断音乐目录下是否有文件if (musicNames.length > 0) {musicList = new ArrayList<>();for (int i = 0; i < musicNames.length; i++) {Music music = new Music();music.setMusicName(musicNames[i]);musicList.add(music);}} else {Toast.makeText(this, "存储卡Music目录里没有音乐文件!", Toast.LENGTH_SHORT).show();}//返回音乐列表return musicList;}/*** 上一曲*/private void previousMusic() throws IOException{//更新索引if (musicIndex>0){musicIndex--;}else {musicIndex = musicList.size() -1;}//位置归零currentPosition = 0;//调用播放方法play();}/*** 播放方法*/private void play() throws IOException {// 重置媒体播放器mp.reset();//获取当前播放的音乐名musicName = musicList.get(musicIndex).getMusicName();//设置播放音乐名tvMusicName.setText("No." + (musicIndex + 1) + " " + musicName.substring(0, musicName.lastIndexOf(".")));// 设置播放源(完整音乐名 = 音乐目录 + 音乐名)mp.setDataSource(musicDir.getAbsolutePath() + "/" + musicName);// 缓冲播放源(从存储卡加载到内存)mp.prepare();//设置当前播放位置标签tvCurrentPosition.setText(CommonUtils.getFormatTime(mp.getCurrentPosition()));//设置音乐播放时长标签tvDuration.setText(CommonUtils.getFormatTime(mp.getDuration()));//获取进度条最大值pbMusicProgress.setMax(mp.getDuration());// 定位到暂停时的播放位置mp.seekTo(currentPosition);// 启动音乐的播放mp.start();// 按钮图标由【播放】图标切换到【暂停】图标btnPlayOrPause.setBackgroundResource(R.drawable.pause_button_selector);}/*** 下一曲*/private void nextMusic() throws IOException{//更新索引if (musicIndex<musicList.size() -1){musicIndex++;}else {musicIndex =0;}//播放位置归零currentPosition = 0;play();}/*** 暂停方法*/private void pause() {// 暂停播放mp.pause();// 保存音乐播放的当前位置currentPosition = mp.getCurrentPosition();// 按钮图标由【暂停】图标切换到【播放】图标btnPlayOrPause.setBackgroundResource(R.drawable.play_button_selector);}/*** 上一曲按钮处理方法* @param view* @throws IOException*/public void doPrevious(View view) throws IOException{previousMusic();}/*** 播放|暂停按钮单击事件处理方法** @param view*/public void doPlayOrPause(View view) throws IOException {// 判断音乐是否在播放if (mp.isPlaying()) {// 暂停音乐pause();} else {// 播放音乐play();}}/*** 下一曲按钮处理方法*/public void doNext(View view) throws IOException{nextMusic();}/*** 销毁回调方法,释放资源*/@Overrideprotected void onDestroy() {super.onDestroy();isRunning = false;thread = null;// 判断音乐是否在播放if (mp.isPlaying()) {mp.stop();}// 释放媒体播放器mp.release();// 销毁媒体播放器mp = null;}
}

安卓实训项目:音乐播放器3.0——实训报告3相关推荐

  1. 安卓实训项目:音乐播放器2.0——实训报告2

    (一)功能要求 添加一个进度条,动态显示音乐的播放进度.----已完成 添加一个标签显示音乐播放的当前位置(格式--mm:ss).----已完成 添加一个标签显示音乐的播放时长(格式--mm:ss). ...

  2. 微信小程序练手项目-音乐播放器

    微信小程序练手项目-音乐播放器 该项目只适合练手,大佬请绕道 项目展示图: 项目介绍 微信小程序音乐播放器 页面: 音乐推荐.播放器.播放列表 功能: 播放.暂停.上一首.下一首.跳转播放列表.实时进 ...

  3. Java web项目——音乐播放器

    Java web项目--音乐播放器 1,需求分析 ①登录并查看自己的音乐列表 ②从本地上传音乐 ③删除某个音乐 ④删除选中的音乐 ⑤查询音乐(支持模糊查询) ⑥添加音乐到喜欢列表且可进行移除 ⑦可在喜 ...

  4. 迷你音乐播放器v1.0正式上线!

    迷你音乐播放器V1.0正式上线! 版本介绍: 1.随机播放切换开关(通过点击专辑图片) 2.通过拖动歌曲名及艺术家名调整歌曲播放进度 3.手机浏览访问支持熄屏播放 4.暂不支持在线搜索功能 快来一起分 ...

  5. Flash版(迷你音乐播放器mp3Player1.0 Beta1 )附源码

    迷你音乐播放器mp3Player1.0 Beta1  ================= //What's new: 主要功能特色: 1.支持歌曲名称,歌手名称以及专辑等关键字搜索. 2.支持随机搜索 ...

  6. 音乐播放器从0到读取手机内的音乐文件——Android Studio小白实训笔记

    前言: 小白的我在经历了两周的Android Studio实训课的学习后,编辑了简易音乐播放器的半成品,通过两周的学习让我对打码又激起了兴趣,很感谢实训老师江哥(博客ID:3052world)的悉心教 ...

  7. 个人项目——音乐播放器(一)

    1 功能需求及技术可行性分析 1.1编写目的   现今社会生活紧张,而欣赏音乐史其中最好的舒缓压力的方式之一,音乐播放类的软 件数不胜数,为什么我还要再写一个播放器出来呢?因为现有的音乐播放器功能实在 ...

  8. 安卓使用服务完成音乐播放器

    安卓音乐播放器 使用Service后台服务实现播放器 自定义封装Music类 利用Fragment+RadioGroup实现页面 自定义Music类 适配器 音乐展示布局文件 Fragment音乐界面 ...

  9. Linux项目:音乐播放器

    文章目录 1.项目介绍 2.前端代码 1.httplib快速搭建一个http服务器 2.B/S双方的数据交互选择JSON数据格式,http请求和响应的正文中采用jsoncpp开源库 3.前段的js代码 ...

最新文章

  1. sklearn:sklearn.preprocessing的MinMaxScaler简介、使用方法之详细攻略
  2. 面试官:Spring事务的传播行为有几种?
  3. linux中and运算符文件重定向,linux 重定向问题详解
  4. 2020年 第11届 蓝桥杯 Java C组 省赛真题详解及小结【第1场省赛 2020.7.5】
  5. IDEA git修改远程仓库地址
  6. mysql 多数据源访问_通过Spring Boot配置动态数据源访问多个数据库的实现代码
  7. DDD~DDD从零起步架构说明
  8. android 程序的目录,Android应用程序目录
  9. (原创)shell脚本编程之---正则表达式的使用
  10. 操作系统知识点_内存管理
  11. sqlplus登录指定服务器,sqlplus 指定数据库
  12. oracle服务怎么手动删除,彻底删除oracle服务
  13. HTML跳转到QQ聊天界面
  14. Emulex光纤卡lpfc配置文件的修改
  15. 实时网速怎么看快慢_怎么测试下载速度(教你安全检测网速快慢)
  16. 树莓派调节显示屏分辨率
  17. js编写计算圆周长和面积
  18. 《浮世绘---湖北人,你到底患了什么病》(转载)
  19. 你可能需要为你的APP适配iOS11
  20. 华为薪资垫底,腾讯阿里被逆袭,第一竟然是…

热门文章

  1. 内核打上yaffs2补丁遇到的问题
  2. c# 写入xml 怪异的事情
  3. 8.1 A Bayesian Methodology for Systemic Risk Assessment in Financial Networks(1)
  4. python3.6 django部署_Centos7 django+uwsgi+nginx+python3.6.8部署
  5. 【控制】《鲁棒控制-线性矩阵不等式处理方法》-俞立老师-目录
  6. 【控制】李亚普诺夫稳定性分析
  7. Ubuntu10.10 配置ssh服务器及samba服务器
  8. [工具]再更新音乐下载软件,MP3音乐无损音乐下载器
  9. 【DIY】热水器升级加装远程wifi控制功能,esp8266远程红外控制热水器启动,稳定连续运行4天了,功能展示终稿...
  10. CYPRESS USB芯片win10驱动