日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2025/4/5 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 安卓实训项目:音乐播放器3.0——实训报告3 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、功能要求
在基于存儲卡音樂播放器V0.2基礎(chǔ)上,增加功能:

添加一個音樂播放列表(顯示歌名)
– 單擊某一首音樂就立刻播放,播放進(jìn)度清零,顯示當(dāng)前音樂的播放時長。
添加一個【上一首】與【下一首】按鈕----完成
– 當(dāng)前音樂為第一首時,單擊【上一首】按鈕,切換到最后一首音樂。----完成
– 當(dāng)前音樂為最后一首時,單擊【下一首】按鈕,切換到第一首音樂。----完成
– 當(dāng)某一首音樂播放完畢后,會自動切換到下一首音樂播放。----完成

二、運行效果

實現(xiàn)步驟
將圖片素材拷貝到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; // 音樂名標(biāo)簽private Button btnPlayOrPause; // 播放|暫停按鈕private int currentPosition; // 音樂當(dāng)前播放位置private TextView tvCurrentPosition; // 顯示當(dāng)前播放位置的標(biāo)簽private TextView tvDuration; // 顯示音樂播放時長的標(biāo)簽private ProgressBar pbMusicProgress; // 音樂播放進(jìn)度條private Thread thread; // 線程private Handler handler; // 消息處理器private boolean isRunning; // 線程循環(huán)控制變量private List<Music> musicList;//音樂數(shù)據(jù)源private ListView lvMusicName;//音樂(數(shù)據(jù)源)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);// 定義存儲讀寫權(quán)限數(shù)組String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};// 檢查是否有讀權(quán)限int permission = ActivityCompat.checkSelfPermission(this, PERMISSIONS_STORAGE[0]);// 如果沒有授權(quán),那么就請求讀權(quán)限if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 0);}//獲取音樂列表musicList = getMusicLists();//判斷列表是否為空if (musicList != null) {//創(chuàng)建適配器adapter = new MusicAdapter(this, musicList);//設(shè)置適配器lvMusicName.setAdapter(adapter);//獲取音樂名標(biāo)簽內(nèi)容(默認(rèn)為第一首)musicName = musicList.get(0).getMusicName();//設(shè)置播放音樂名tvMusicName.setText("No." + (musicIndex + 1) + " " + musicName.substring(0, musicName.lastIndexOf(".")));//初始化播放器mp = new MediaPlayer();try {//設(shè)置播放源mp.setDataSource(musicDir.getAbsolutePath() + "/" + musicName);// 緩沖播放源(從存儲卡加載到內(nèi)存)mp.prepare();//設(shè)置當(dāng)前播放位置標(biāo)簽tvCurrentPosition.setText(CommonUtils.getFormatTime(mp.getCurrentPosition()));//設(shè)置音樂播放時長標(biāo)簽tvDuration.setText(CommonUtils.getFormatTime(mp.getDuration()));//獲取進(jìn)度條最大值pbMusicProgress.setMax(mp.getDuration());} catch (IOException e) {e.printStackTrace();}//設(shè)置循環(huán)變量為真isRunning = true;//創(chuàng)建子線程,定時發(fā)送消息thread = new Thread(new Runnable() {@Overridepublic void run() {while (isRunning) {handler.sendEmptyMessage(0x001);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});//啟動子線程thread.start();//創(chuàng)建消息處理器,接受子線程發(fā)送的消息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));}}}};//設(shè)置監(jiān)聽器lvMusicName.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {//獲取索引musicIndex = position;//進(jìn)度歸零currentPosition = 0;try {play();} catch (IOException e) {e.printStackTrace();}}});mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mediaPlayer) {//當(dāng)前音樂播放完畢,切換下一首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);//定義數(shù)組名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;//調(diào)用播放方法play();}/*** 播放方法*/private void play() throws IOException {// 重置媒體播放器mp.reset();//獲取當(dāng)前播放的音樂名musicName = musicList.get(musicIndex).getMusicName();//設(shè)置播放音樂名tvMusicName.setText("No." + (musicIndex + 1) + " " + musicName.substring(0, musicName.lastIndexOf(".")));// 設(shè)置播放源(完整音樂名 = 音樂目錄 + 音樂名)mp.setDataSource(musicDir.getAbsolutePath() + "/" + musicName);// 緩沖播放源(從存儲卡加載到內(nèi)存)mp.prepare();//設(shè)置當(dāng)前播放位置標(biāo)簽tvCurrentPosition.setText(CommonUtils.getFormatTime(mp.getCurrentPosition()));//設(shè)置音樂播放時長標(biāo)簽tvDuration.setText(CommonUtils.getFormatTime(mp.getDuration()));//獲取進(jìn)度條最大值pbMusicProgress.setMax(mp.getDuration());// 定位到暫停時的播放位置mp.seekTo(currentPosition);// 啟動音樂的播放mp.start();// 按鈕圖標(biāo)由【播放】圖標(biāo)切換到【暫停】圖標(biāo)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();// 保存音樂播放的當(dāng)前位置currentPosition = mp.getCurrentPosition();// 按鈕圖標(biāo)由【暫停】圖標(biāo)切換到【播放】圖標(biāo)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();}/*** 銷毀回調(diào)方法,釋放資源*/@Overrideprotected void onDestroy() {super.onDestroy();isRunning = false;thread = null;// 判斷音樂是否在播放if (mp.isPlaying()) {mp.stop();}// 釋放媒體播放器mp.release();// 銷毀媒體播放器mp = null;} }

總結(jié)

以上是生活随笔為你收集整理的安卓实训项目:音乐播放器3.0——实训报告3的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。