生活随笔
收集整理的這篇文章主要介紹了
安卓实训项目:音乐播放器3.0——实训报告3
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、功能要求
在基于存儲卡音樂播放器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的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。