文章目次
一、项目功能要求
- 数据源来自扫描存储卡MP3音乐得到的列表
- 播放列表显示音乐文件(仅仅显示音乐名,没有扩展名)
- 使用自界说Service类来实现音乐的播放与暂停以及进度的更新
- 界面类(Activity)与服务类(Service)之间通过广播吸收者举行通信
- 主界面包罗的要素
– 播放列表
– 可设置播放模式
– 显示当前音乐名
– 拖拽条显示和设置播放进度
– 显示播放进度值和播放时长
– 包罗上一首按钮、下一首按钮、播放|暂停按钮
- 启动界面 - 包罗软件名称、版本号、作者等信息
二、涉及知识点
- 安卓核心组件:运动(Activity)、服务(Service)、广播吸收者(BroadcastReceiver)
- 意图(Intent),通过意图激活Activity和Service、发送广播
- 安卓常用控件:按钮(Button)、标签(TextView)、进度条(ProgressBar)、拖拽条(SeekBar)、列表控件(ListView)、单选按钮(RadioButton)、媒体播放器(MediaPlayer)、图像视图(ImageView)
- 继承基适配器(BaseAdapter)创建自界说适配器
- 数组列表(ArrayList)
- 补间动画(Tween Animation)
- 线程(Thread)
三、实现思路
分为六个版本,逐步增加功能,直到最后实现全部功能。
1、基于存储卡音乐播放器V0.1
2、基于存储卡音乐播放器V0.2
- 功能:播放存储卡指定目次里某一首音乐,显示播放进度与音乐时长
3、基于存储卡音乐播放器V0.3
- 功能:列表显示存储卡指定目次里全部音乐,显示播放进度与音乐时长
4、基于存储卡音乐播放器V0.4
- 功能:列表显示存储卡全部音乐,显示播放进度与音乐时长
5、基于存储卡音乐播放器V0.5
- 功能:列表显示存储卡全部音乐,显示播放进度与音乐时长,播放任务交给音乐服务类来完成,使用广播吸收器实现界面类与服务类之间的通信。
6、基于存储卡音乐播放器V0.6
- 功能:添加启动画面,添加音乐播放模式功能:顺序播放、随机播放、单首循环,将进度条改成拖拽条,用户通过拖拽可自行设置音乐播放进度值。列表显示存储卡全部音乐,显示播放进度与音乐时长,播放任务交给音乐服务类来完成,使用广播吸收器实现界面类与服务类之间的通信。
四、项目素材下载
1、音频素材下载
链接: https://pan.baidu.com/s/1vfW-HNSpgbhgtnmvMNa-YA
提取码: 3qav
2、图片素材下载
链接: https://pan.baidu.com/s/1BtQRHNmrFUj6trqGFx_ULA
提取码: 887h
五、基于存储卡音乐播放器V0.1
(一)功能要求
- 播放存储卡上一首音乐
- 播放|暂停按钮,可切换
- 显示要播放的音乐名
- 要求窗口有配景图片
(二)运行效果
(三)涉及知识点
- 线性布局(LinearLayout)
- 标签(TextView)
- 按钮(Button)
- 媒体播放器(MediaPlayer)
(1)初始化
(2)设置播放源
(3)判断是否播放
(4)获取播放当前位置
(5)注册播放完成监听器
- 读取存储卡指定目次里的文件
- 控件配景选择器
(四)实现步调
1、创建安卓应用【SDCardMusicPlayerV0.1】
2、将MP3音频文件放到存储卡指定位置
- 启动DDMS
- 找到Music目次
- 从电脑上添加MP3音频文件到Music目次
3、将图片素材拷贝到Drawable目次
4、创建按钮配景图片选择器
(1)播放按钮配景图片选择器 - play_button_selector.xml
(2)暂停按钮配景图片选择器 - pause_button_selector.xml
5、主布局资源文件activity_main.xml
6、在项目清单文件里授权读外置存储卡
7、主界面类 - MainActivity
(1)声明变量
(2)通过资源标识符获取控件实例
(3)查抄外置存储卡读写权限
(4)获取音乐文件存放目次
- Environment类包罗目次常量
- 此中,Environment.DIRECTORY_MUSIC对应的就是外置存储卡上的/storage/emulated/0/Music目次
(5)获取音乐文件并设置音乐名标签
(6)启动应用,查察效果
(7)创建媒体播放器,并注册完成监听器
(8)创建播放方法 - play()
(9)编写暂停方法 - pause()
(10)编写播放|暂停按钮单击事件处理处罚方法
(11)编写销毁回调方法,释放资源
(12)查察主界面完整源代码
- package net.hw.sdcard_musicplayer_v01;import android.Manifest;import android.content.pm.PackageManager;import android.media.MediaPlayer;import android.os.Bundle;import android.os.Environment;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import java.io.File;import java.io.IOException;/** * 功能:基于存储卡音乐播放器V0.1 * 作者:华卫 * 日期:2020年12月31日 */public class MainActivity extends AppCompatActivity { private MediaPlayer mp; // 媒体播放器 private File musicDir; // 音乐存放目次 private String musicName; // 音乐文件名 private TextView tvMusicName; // 音乐名标签 private Button btnPlayOrPause; // 播放|暂停按钮 private int currentPosition; // 音乐当前播放位置 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 使用布局资源文件设置用户界面 setContentView(R.layout.activity_main); // 通过资源标识符获取控件实例 tvMusicName = findViewById(R.id.tvMusicName); btnPlayOrPause = findViewById(R.id.btnPlayOrPause); // 界说存储读写权限数组 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); } // 获取音乐文件存放目次 musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); try { // 获取音乐文件存放目次里的第一首音乐文件名 musicName = musicDir.list()[0]; // 设置音乐名标签,要去掉扩展名 tvMusicName.setText("音乐名:" + musicName.substring(0, musicName.lastIndexOf("."))); } catch (Exception e) { Toast.makeText(this, "存储卡Music目次里没有音乐文件!", Toast.LENGTH_SHORT).show(); } // 实例化媒体播放器 mp = new MediaPlayer(); // 给媒体播放器注册完成监听器 mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // 提示用户当前音乐播放完毕 Toast.makeText(MainActivity.this, "当前音乐播放完毕!", Toast.LENGTH_SHORT).show(); // 当前播放位置清零 currentPosition = 0; // 按钮图标由【暂停】图标切换到【播放】图标 btnPlayOrPause.setBackgroundResource(R.drawable.play_button_selector); } }); } /** * 播放方法 */ private void play() throws IOException { // 重置媒体播放器 mp.reset(); // 设置播放源(完整音乐名 = 音乐目次 + 音乐名) mp.setDataSource(musicDir.getAbsolutePath() + "/" + musicName); // 缓冲播放源(从存储卡加载到内存) mp.prepare(); // 定位到暂停时的播放位置 mp.seekTo(currentPosition); // 启动音乐的播放 mp.start(); // 按钮图标由【播放】图标切换到【暂停】图标 btnPlayOrPause.setBackgroundResource(R.drawable.pause_button_selector); } /** * 暂停方法 */ private void pause() { // 暂停播放 mp.pause(); // 生存音乐播放的当前位置 currentPosition = mp.getCurrentPosition(); // 按钮图标由【暂停】图标切换到【播放】图标 btnPlayOrPause.setBackgroundResource(R.drawable.play_button_selector); } /** * 播放|暂停按钮单击事件处理处罚方法 * * @param view */ public void doPlayOrPause(View view) throws IOException { // 判断音乐是否在播放 if (mp.isPlaying()) { // 暂停音乐 pause(); } else { // 播放音乐 play(); } } /** * 销毁回调方法,释放资源 */ @Override protected void onDestroy() { super.onDestroy(); // 判断音乐是否在播放 if (mp.isPlaying()) { mp.stop(); } // 释放媒体播放器 mp.release(); // 销毁媒体播放器 mp = null; }}
复制代码 8、启动应用,查察效果
来源:https://blog.csdn.net/howard2005/article/details/112009127
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |