900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 简单音乐播放器的实现

简单音乐播放器的实现

时间:2021-01-13 14:33:29

相关推荐

简单音乐播放器的实现

5月14日 星期四 晴☀

今天在慕课学习了音频播放器的实现,做完了真的是高兴啊!现在把这个播放器分享给大家!

先看看结果:

操作方法:

安装后,首先要打开存储权限,不然直接打开会被告知“对不起,暂时没有音乐文件”;存储权限打开后,在手机文件目录下,排序->按修改时间排序->找到一个名为“playmusic”的文件夹,这就是我们要存歌曲的文件夹,或者我们可以手动创建playmusic文件夹;从手机下载几首音频文件,复制到步骤2所说的文件夹下,重新打开安装的应用,就可以使用了;

源码分享

layout/main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ListViewandroid:id="@+id/lvNames"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

layout/play.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/tvMusic"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="music.mp3"android:textColor="#000000"android:textSize="20dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/btnLast"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="◀" /><Buttonandroid:id="@+id/btnNext"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="▶" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/btnPlay"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="播放" /><Buttonandroid:id="@+id/btnStopTemp"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="暂停" /><Buttonandroid:id="@+id/btnStop"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="停止" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/btnMode1"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="顺序播放" /><Buttonandroid:id="@+id/btnMode2"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="随机播放" /><Buttonandroid:id="@+id/btnMode3"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="单曲循环" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/btnTurnDown"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="-" /><Buttonandroid:id="@+id/btnTurnUp"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="+" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><SeekBarandroid:id="@+id/seekbar"android:layout_width="match_parent"android:layout_height="wrap_content" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tvProgressLeft"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:paddingLeft="5dp" /><TextViewandroid:id="@+id/tvProgressRight"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="right"android:paddingRight="5dp" /></LinearLayout></LinearLayout></LinearLayout>

layout/item_message.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_head"android:layout_width="60dp"android:layout_height="60dp"android:scaleType="fitXY"android:src="@mipmap/ic_launcher" /><LinearLayoutandroid:id="@+id/ll"android:layout_width="300dp"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_toRightOf="@+id/iv_head"android:orientation="vertical"><TextViewandroid:id="@+id/tvName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="歌曲名" /><TextViewandroid:id="@+id/tvLocation"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="歌曲保存位置" /></LinearLayout><TextViewandroid:id="@+id/tvTime"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_toRightOf="@+id/ll"android:text="3:56" /></RelativeLayout>

com.example.music_player.MainActivity

package com.example.music_player;import android.content.Context;import android.content.Intent;import android.media.MediaPlayer;import android.os.Bundle;import android.os.Environment;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import java.io.File;import java.io.FileFilter;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.concurrent.TimeUnit;public class MainActivity extends AppCompatActivity {protected Context context;private String MEDIA_PATH = "";//SD卡路径private ListView listView;private ArrayList<HashMap<String, Object>> listItems = new ArrayList<HashMap<String, Object>>();//存放歌曲相关信息private FileFilter fileFilter = new FileFilter() {@Overridepublic boolean accept(File pathname) {return !pathname.isDirectory() && pathname.getName().matches("^.*?\\.(mp3|mid|wma)$");}};private SimpleAdapter simpleAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);listView = findViewById(R.id.lvNames);//1. 判断SD卡的playmusic目录及音乐文件功能if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {MEDIA_PATH = Environment.getExternalStorageDirectory().toString();} else {Toast.makeText(MainActivity.this, "对不起,SD卡不存在", Toast.LENGTH_SHORT).show();return;}File folder = new File(MEDIA_PATH + "/playmusic/");if (!folder.exists()) {folder.mkdir();Toast.makeText(MainActivity.this, "对不起,暂时没有音乐文件", Toast.LENGTH_SHORT).show();finish();return;}//2. 定义音乐文件扩展名(定义一个FileFilter)File[] fileArr = folder.listFiles(fileFilter);//3. 给ListView装配数据//将满足扩展名的文件信息(图片,歌曲名,存放位置,播放时间等)存放在ArrayList中HashMap<String, Object> map;for (File file : fileArr) {map = new HashMap<String, Object>();map.put("icon", R.mipmap.ic_launcher);//图片map.put("fileName", file.getName());//歌曲名map.put("filePathName", file.getAbsolutePath());//歌曲存放路径MediaPlayer mediaPlayer = new MediaPlayer();try {mediaPlayer.setDataSource(file.getAbsolutePath());mediaPlayer.prepare();int mTime = mediaPlayer.getDuration();long minutes = TimeUnit.MILLISECONDS.toMinutes(mTime);long seconds = TimeUnit.MILLISECONDS.toSeconds(mTime) - minutes * 60;String sTime = String.format("%d:%d", minutes, seconds);map.put("fileTime", sTime);//音乐播放时间} catch (IOException e) {e.printStackTrace();}listItems.add(map);}//4. 将数据与ListView绑定(对于每一行的布局文件)String[] from = new String[]{"icon", "fileName", "filePathName", "fileTime"};int[] to = new int[]{R.id.iv_head, R.id.tvName, R.id.tvLocation, R.id.tvTime};simpleAdapter = new SimpleAdapter(MainActivity.this, listItems, R.layout.item_message, from, to);listView.setAdapter(simpleAdapter);//5. 单机歌曲名,会打开PlayActivity并将歌曲信息传入listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Intent intent = new Intent(MainActivity.this, PlayActivity.class);intent.putExtra("index", position);intent.putExtra("list", listItems);startActivity(intent);}});}}

com.example.music_player.PlayActivity

package com.example.music_player;import android.content.Intent;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.text.TextUtils;import android.view.View;import android.widget.Button;import android.widget.SeekBar;import android.widget.TextView;import android.widget.Toast;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.Random;public class PlayActivity extends AppCompatActivity {private TextView tvMusic, tvProgressLeft, tvProgressRight;private Button btnLast, btnNext, btnPlay, btnStopTemp, btnStop, btnMode1, btnMode2, btnMode3, btnTurnDown, btnTurnUp;private SeekBar seekbar;private AudioManager audioManager;private MediaPlayer mediaPlayer = new MediaPlayer();private ArrayList<HashMap<String, Object>> musicList;private int index;private int playMode = 0;//播放模式:0-顺序播放,1-随机播放,2-单曲循环private Random random = new Random();//随机播放歌曲的序号Handler handler = new Handler() {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);switch (msg.what) {case 9999:seekbar.setProgress(msg.arg2);seekbar.setMax(msg.arg1);int leftTime = msg.arg2 / 1000;int leftMinute = leftTime / 60;int leftSecond = leftTime % 60;tvProgressLeft.setText(leftMinute + ":" + leftSecond);int rightTime = (msg.arg1 - msg.arg2) / 1000;int rightMinute = rightTime / 60;int rightSecond = rightTime % 60;tvProgressRight.setText(rightMinute + ":" + rightSecond);break;}}};Runnable runnable = new Runnable() {@Overridepublic void run() {try {while (true) {Thread.sleep(200);Message message = new Message();message.what = 9999;message.arg1 = mediaPlayer.getDuration();//歌曲的总进度message.arg2 = mediaPlayer.getCurrentPosition();//歌曲当前进度handler.sendMessage(message);}} catch (InterruptedException e) {e.printStackTrace();}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.play);initView();audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);final Intent intent = this.getIntent();index = intent.getIntExtra("index", 0);musicList = (ArrayList<HashMap<String, Object>>) intent.getSerializableExtra("list");//播放歌曲及显示相关信息//1. 显示歌曲名tvMusic.setText((CharSequence) musicList.get(index).get("fileName"));//2. 播放歌曲playMusic(index);btnLast.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {index--;if (index < 0) {Toast.makeText(PlayActivity.this, "没有更多歌曲了", Toast.LENGTH_SHORT).show();return;}playMusic(index);}});btnNext.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {index++;if (index >= musicList.size()) {Toast.makeText(PlayActivity.this, "没有更多歌曲了", Toast.LENGTH_SHORT).show();return;}playMusic(index);}});btnStop.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mediaPlayer.isPlaying()) {mediaPlayer.stop();}}});btnStopTemp.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mediaPlayer.isPlaying()) {mediaPlayer.pause();}}});btnPlay.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mediaPlayer.start();}});btnTurnUp.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);}});btnTurnDown.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);}});btnMode1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {playMode = 0;//顺序播放}});btnMode2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {playMode = 1;//随机播放}});btnMode3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {playMode = 2;//单曲循环}});seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {//当进度改变时的操作}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {//当拖动滑块开始执行的操作}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {//当停止拖动滑块开始进行的操作mediaPlayer.seekTo(seekBar.getProgress());}});}void playMusic(int index) {tvMusic.setText(musicList.get(index).get("fileName").toString());//显示歌曲名String path = musicList.get(index).get("filePathName").toString();//取出歌曲保存位置if (TextUtils.isEmpty(path)) {return;}if (mediaPlayer.isPlaying()) {mediaPlayer.stop();}mediaPlayer.release();mediaPlayer = null;mediaPlayer = new MediaPlayer();mediaPlayer.reset();try {mediaPlayer.setDataSource(path);mediaPlayer.prepare();//mediaPlayer.start();mediaPlayer.setOnPreparedListener(new SetPreparedListener());//设置当歌曲准备完毕后的监听事件mediaPlayer.setOnCompletionListener(new SetCompletionListener());//设置一首歌播放完的监听事件} catch (IOException e) {e.printStackTrace();}}void initView() {tvMusic = findViewById(R.id.tvMusic);tvProgressLeft = findViewById(R.id.tvProgressLeft);tvProgressRight = findViewById(R.id.tvProgressRight);btnLast = findViewById(R.id.btnLast);btnNext = findViewById(R.id.btnNext);btnPlay = findViewById(R.id.btnPlay);btnStopTemp = findViewById(R.id.btnStopTemp);btnStop = findViewById(R.id.btnStop);btnMode1 = findViewById(R.id.btnMode1);btnMode2 = findViewById(R.id.btnMode2);btnMode3 = findViewById(R.id.btnMode3);btnTurnDown = findViewById(R.id.btnTurnDown);btnTurnUp = findViewById(R.id.btnTurnUp);seekbar = findViewById(R.id.seekbar);}class SetPreparedListener implements MediaPlayer.OnPreparedListener {@Overridepublic void onPrepared(MediaPlayer mp) {//1. 开始播放mediaPlayer.start();//2. 更新seekbar的进度,需要使用handler,runnable配合new Thread(runnable).start();}}class SetCompletionListener implements MediaPlayer.OnCompletionListener {@Overridepublic void onCompletion(MediaPlayer mp) {switch (playMode) {case 0://顺序播放index++;if (index >= musicList.size()) {Toast.makeText(PlayActivity.this, "没有更多歌曲了", Toast.LENGTH_SHORT).show();return;}playMusic(index);break;case 1://随机播放if (!musicList.isEmpty()) {index = random.nextInt(musicList.size());System.out.println(index);playMusic(index);}break;case 2://单曲循环mediaPlayer.seekTo(0);mediaPlayer.start();break;}}}}

写在最后

这算是安卓学习过程中,到目前为止比较有成就感的几次中的一次啦,嘻嘻(●’◡’●)

Github项目地址

Github项目地址

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。