詳解Android應(yīng)用開發(fā)--MP3音樂播放器代碼實(shí)現(xiàn)(一)
需求1:將內(nèi)存卡中的MP3音樂讀取出來(lái)并顯示到列表當(dāng)中
1.從數(shù)據(jù)庫(kù)中查詢所有音樂數(shù)據(jù),保存到List集合當(dāng)中,List當(dāng)中存放的是Mp3Info對(duì)象
2.迭代List集合,把每一個(gè)Mp3Info對(duì)象的所有屬性,保存到Map對(duì)象當(dāng)中
3.定義一個(gè)List集合,把Map對(duì)象添加到List集合當(dāng)中
4.通過(guò)定義一個(gè)SimpleAdpter,調(diào)用setAdpter方法,將數(shù)據(jù)顯示到列表當(dāng)中
/** * 用于從數(shù)據(jù)庫(kù)中查詢歌曲的信息,保存在List當(dāng)中 * * @return */ public List<Mp3Info> getMp3Infos() { Cursor cursor = getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>(); for (int i = 0; i < cursor.getCount(); i++) { Mp3Info mp3Info = new Mp3Info(); cursor.moveToNext(); long id = cursor.getLong(cursor .getColumnIndex(MediaStore.Audio.Media._ID)); //音樂id String title = cursor.getString((cursor .getColumnIndex(MediaStore.Audio.Media.TITLE)));//音樂標(biāo)題 String artist = cursor.getString(cursor .getColumnIndex(MediaStore.Audio.Media.ARTIST));//藝術(shù)家 long duration = cursor.getLong(cursor .getColumnIndex(MediaStore.Audio.Media.DURATION));//時(shí)長(zhǎng) long size = cursor.getLong(cursor .getColumnIndex(MediaStore.Audio.Media.SIZE)); //文件大小 String url = cursor.getString(cursor .getColumnIndex(MediaStore.Audio.Media.DATA)); //文件路徑 int isMusic = cursor.getInt(cursor .getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否為音樂 if (isMusic != 0) { //只把音樂添加到集合當(dāng)中 mp3Info.setId(id); mp3Info.setTitle(title); mp3Info.setArtist(artist); mp3Info.setDuration(duration); mp3Info.setSize(size); mp3Info.setUrl(url); mp3Infos.add(mp3Info); } } return mp3Infos; }
/** * 填充列表 * @param mp3Infos */ public void setListAdpter(List<Mp3Info> mp3Infos) { List<HashMap<String, String>> mp3list = new ArrayList<HashMap<String, String>>(); for (Iterator iterator = mp3Infos.iterator(); iterator.hasNext();) { Mp3Info mp3Info = (Mp3Info) iterator.next(); HashMap<String, String> map = new HashMap<String, String>(); map.put("title", mp3Info.getTitle()); map.put("Artist", mp3Info.getArtist()); map.put("duration", String.valueOf(mp3Info.getDuration())); map.put("size", String.valueOf(mp3Info.getSize())); map.put("url", mp3Info.getUrl()); mp3list.add(map); } mAdapter = new SimpleAdapter(this, mp3list, R.layout.music_list_item_layout, new String[] { "title", "Artist", "duration" }, new int[] { R.id.music_title, R.id.music_Artist, R.id.music_duration }); mMusiclist.setAdapter(mAdapter); }
實(shí)現(xiàn)效果如圖:
需求2:點(diǎn)擊列表的每一項(xiàng),啟動(dòng)一個(gè)服務(wù)來(lái)播放音樂
1. 注冊(cè)條目點(diǎn)擊監(jiān)聽器OnItemClickListener
2. 定義一個(gè)實(shí)現(xiàn)OnItemClickListener接口的內(nèi)部類
3. 定義一個(gè)繼承Service的服務(wù)類PlayerServie
1. 注冊(cè)條目點(diǎn)擊監(jiān)聽器OnItemClickListener
mMusiclist = (ListView) findViewById(R.id.music_list); mMusiclist.setOnItemClickListener(new MusicListItemClickListener()); mp3Infos = getMp3Infos(); setListAdpter(getMp3Infos());
2. 定義一個(gè)實(shí)現(xiàn)OnItemClickListener接口的內(nèi)部類
private class MusicListItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(mp3Infos != null) { Mp3Info mp3Info = mp3Infos.get(position); Log.d("mp3Info-->", mp3Info.toString()); Intent intent = new Intent(); intent.putExtra("url", mp3Info.getUrl()); intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG); intent.setClass(MainActivity.this, PlayerService.class); startService(intent); //啟動(dòng)服務(wù) } } }
3. 定義一個(gè)繼承Service的服務(wù)類PlayerServie(未完善的Service類)
package com.wwj.sb.service; import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.media.MediaPlayer.OnPreparedListener; import android.os.IBinder; import com.wwj.sb.domain.AppConstant; @SuppressLint("NewApi") public class PlayerService extends Service { private MediaPlayer mediaPlayer = new MediaPlayer(); //媒體播放器對(duì)象 private String path; //音樂文件路徑 private boolean isPause; //暫停狀態(tài) @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(mediaPlayer.isPlaying()) { stop(); } path = intent.getStringExtra("url"); int msg = intent.getIntExtra("MSG", 0); if(msg == AppConstant.PlayerMsg.PLAY_MSG) { play(0); } else if(msg == AppConstant.PlayerMsg.PAUSE_MSG) { pause(); } else if(msg == AppConstant.PlayerMsg.STOP_MSG) { stop(); } return super.onStartCommand(intent, flags, startId); } /** * 播放音樂 * @param position */ private void play(int position) { try { mediaPlayer.reset();//把各項(xiàng)參數(shù)恢復(fù)到初始狀態(tài) mediaPlayer.setDataSource(path); mediaPlayer.prepare(); //進(jìn)行緩沖 mediaPlayer.setOnPreparedListener(new PreparedListener(position));//注冊(cè)一個(gè)監(jiān)聽器 } catch (Exception e) { e.printStackTrace(); } } /** * 暫停音樂 */ private void pause() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); isPause = true; } } /** * 停止音樂 */ private void stop(){ if(mediaPlayer != null) { mediaPlayer.stop(); try { mediaPlayer.prepare(); // 在調(diào)用stop后如果需要再次通過(guò)start進(jìn)行播放,需要之前調(diào)用prepare函數(shù) } catch (Exception e) { e.printStackTrace(); } } } @Override public void onDestroy() { if(mediaPlayer != null){ mediaPlayer.stop(); mediaPlayer.release(); } } /** * * 實(shí)現(xiàn)一個(gè)OnPrepareLister接口,當(dāng)音樂準(zhǔn)備好的時(shí)候開始播放 * */ private final class PreparedListener implements OnPreparedListener { private int positon; public PreparedListener(int positon) { this.positon = positon; } @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); //開始播放 if(positon > 0) { //如果音樂不是從頭播放 mediaPlayer.seekTo(positon); } } } }
以上代碼實(shí)現(xiàn)了兩個(gè)需求,顯示音樂列表和實(shí)現(xiàn)列表點(diǎn)擊事件啟動(dòng)Servic。下次會(huì)實(shí)現(xiàn)控制音樂播放的需求。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android實(shí)現(xiàn)通過(guò)NFC讀取卡號(hào)
這篇文章主要介紹了android實(shí)現(xiàn)通過(guò)NFC讀取卡號(hào),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Android學(xué)習(xí)教程之圖片毛玻璃效果(4)
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)教程之圖片毛玻璃效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Android NDK開發(fā)的環(huán)境搭建與簡(jiǎn)單示例
本文主要介紹Android NDK的知識(shí),這里整理了相關(guān)資料,來(lái)說(shuō)明如何搭建相應(yīng)環(huán)境和簡(jiǎn)單實(shí)例,幫助大家理解,有興趣的小伙伴可以參考下2016-09-09Flutter彈性布局Flex水平排列Row垂直排列Column使用示例
這篇文章主要為大家介紹了Flutter彈性布局Flex水平排列Row垂直排列Column使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Android使用觀察者模式Observer實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)監(jiān)聽
這篇文章主要為大家詳細(xì)介紹了Android使用觀察者模式Observer實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)監(jiān)聽,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05