在基于存储卡音乐播放器V0.1基础上,增加功能:
添加一个进度条,动态显示音乐的播放进度。
添加一个标签显示音乐播放的当前位置(格式——mm:ss)。
添加一个标签显示音乐的播放时长(格式——mm:ss)。
涉及知识点
线性布局(linearLayout)
标签(TextVIEw)
按钮(button)
媒体播放器(MediaPlayer)
读取存储卡指定目录里的文件
控件背景选择器
进度条(Progressbar)
线程(Thread)
消息处理器(Handler)
<TextVIEw androID:ID="@+ID/tvMusicname" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:textcolor="#0000ff" androID:textSize="20sp" /><linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_margintop="10dp" androID:layout_marginBottom="10dp" androID:gravity="center" androID:orIEntation="horizontal"> <TextVIEw androID:ID="@+ID/tvCurrentposition" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:textcolor="#ff0000" /> <Progressbar androID:ID="@+ID/pbMusicProgress" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="6" /> <TextVIEw androID:ID="@+ID/tvDuration" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:textcolor="#ff00ff" /></linearLayout><linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:gravity="center" androID:orIEntation="horizontal"> <button androID:ID="@+ID/btnPlayOrPause" androID:layout_wIDth="60dp" androID:layout_height="50dp" androID:background="@drawable/play_button_selector" androID:onClick="doPlayOrPause" /></linearLayout>
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210105095234389.png) package com.example.v02.ui;
import androIDx.annotation.NonNull;
import androIDx.appcompat.app.AppCompatActivity;
import androIDx.core.app.ActivityCompat;
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.button;
import androID.Widget.Progressbar;
import androID.Widget.TextVIEw;
import androID.Widget.Toast;
import com.example.v02.R;
import com.example.v02.ui.util.CommonUtils;
import java.io.file;
import java.io.IOException;
import static androID.content.pm.PackageManager.;
import static androID.Widget.Toast.;
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; // 线程循环控制变量
@OverrIDeprotected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 利用布局资源文件设置用户界面 setContentVIEw(R.layout.activity_main); // 通过资源标识符获取控件实例 tvMusicname = findVIEwByID(R.ID.tvMusicname); btnPlayOrPause = findVIEwByID(R.ID.btnPlayOrPause); 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); } // 获取音乐文件存放目录 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(); 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(); } // 给媒体播放器注册完成监听器 mp.setonCompletionListener(new MediaPlayer.OnCompletionListener() { @OverrIDe public voID onCompletion(MediaPlayer mp) { // 提示用户当前音乐播放完毕 Toast.makeText(MainActivity.this, "当前音乐播放完毕!", Toast.LENGTH_SHORT).show(); // 当前播放位置清零 currentposition = 0; // 将当前播放位置标签文本归零 tvCurrentposition.setText(CommonUtils.getFormatTime(currentposition)); // 将音乐播放进度条的进度值归零 pbMusicProgress.setProgress(currentposition); // 按钮图标由【暂停】图标切换到【播放】图标 btnPlayOrPause.setBackgroundResource(R.drawable.play_button_selector); } }); // 设置线程循环控制变量为真 isRunning = true; // 创建子线程,定时发送消息 thread = new Thread(new Runnable() { @OverrIDe public voID run() { while (isRunning) { // 向主线程发送消息 handler.sendEmptyMessage(0x001); try { // 让线程睡眠500毫秒 Thread.sleep(500); } catch (InterruptedException e) { e.printstacktrace(); } } } }); // 启动子线程 thread.start(); // 创建消息处理器,接收子线程发送的消息 handler = new Handler() { @OverrIDe public voID handleMessage(@NonNull Message msg) { super.handleMessage(msg); // 根据子线程发送的消息进行相应处理 if (msg.what == 0x001) { // 判断音乐是否在播放 if (mp != null && mp.isPlaying()) { // 获取当前播放位置 currentposition = mp.getCurrentposition(); // 更新音乐播放进度条的进度值 pbMusicProgress.setProgress(currentposition); // 更新当前播放位置标签的内容 tvCurrentposition.setText(CommonUtils.getFormatTime(currentposition)); } } } };}/** * 播放方法 */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(); }}/** * 销毁回调方法,释放资源 */@OverrIDeprotected voID onDestroy() { super.onDestroy(); // 停止线程 isRunning = false; // 销毁线程 thread = null; // 判断音乐是否在播放 if (mp.isPlaying()) { mp.stop(); } // 释放媒体播放器 mp.release(); // 销毁媒体播放器 mp = null;}
}
实训好难哟 总结
以上是内存溢出为你收集整理的安卓第二次实训全部内容,希望文章能够帮你解决安卓第二次实训所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)