版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 畢業(yè)論文</b></p><p> 題目 基于安卓Android的MP3播放器 </p><p> 的設計與實現(xiàn) </p><p> 學生所在學院 電氣信息學院 </p><p> 專 業(yè) 軟件工程
2、 </p><p> 學 號 </p><p> 學 生 姓 名 </p><p> 指 導 教 師 </p><p> 起 止 日 期
3、 </p><p><b> 摘要</b></p><p> Android平臺是Google針對移動設備所推出的一個操作平臺,此平臺是以Apache開源許可的方式的進行發(fā)布的,所以使用該系統(tǒng)是免費的,所以開發(fā)人員能夠在該平臺上開發(fā)屬于自己的應用。</p><p> Android平臺是由“操作系統(tǒng)”、“中間件”、“用戶界
4、面”和“應用程序”組成的。它采用了軟件堆層的架構設計,分為三部分,其中底層以Linux內(nèi)核工作為基礎,只提供基本功能來處理事件;中間層包括函數(shù)庫和虛擬機,負責系統(tǒng)運行所必須的環(huán)境;最上層是各種應用程序,包括Android系統(tǒng)自帶的通話、短信、相機等應用;應用軟件則由其他自由開發(fā)人員或公司自行開發(fā),然后發(fā)布到Android應用市場供用戶下載。</p><p> 本文以Android開發(fā)平臺為基礎,首先簡要介紹了A
5、ndroid平臺的發(fā)展歷程、以及當前國內(nèi)外關于音樂播放器的發(fā)展現(xiàn)狀。然后描述了Android開發(fā)平臺的開發(fā)環(huán)境的搭建。之后便對本播放器做了一個詳細的需求分析。再然后便開始描述本播放器所需使用的數(shù)據(jù)庫的設計。然后對本播放器中的所有功能界面進行詳細介紹和功能實現(xiàn)。</p><p> 關鍵詞:Android 音樂播放器 Android平臺的開發(fā)與設計</p><p><b> 目錄
6、</b></p><p><b> 摘要I</b></p><p><b> 1. 概述1</b></p><p> 1.1 項目背景1</p><p> 1.2 國內(nèi)外相關研究現(xiàn)狀及發(fā)展趨勢1</p><p> 1.3 項目研究意義2&
7、lt;/p><p> 1.4 本文主要內(nèi)容2</p><p> 2. Android開發(fā)環(huán)境搭建3</p><p> 3. 項目需求分析4</p><p><b> 3.1 目的4</b></p><p> 3.2 系統(tǒng)背景4</p><p> 3.3
8、問題說明4</p><p> 3.4 系統(tǒng)范圍4</p><p> 3.5 用例圖及用例描述4</p><p> 3.6 功能摘要6</p><p> 3.7 假定與約束7</p><p> 4. 數(shù)據(jù)庫設計8</p><p> 4.1 數(shù)據(jù)庫概念設計8</p&g
9、t;<p> 4.2 數(shù)據(jù)表設計8</p><p> 4.3 數(shù)據(jù)庫的連接及操作類的編寫11</p><p> 5. 項目實現(xiàn)14</p><p> 5.1 歡迎界面14</p><p> 5.1.1 歡迎界面概述14</p><p> 5.1.2 歡迎界面技術分析14</p
10、><p> 5.2 播放器主界面15</p><p> 5.2.1 播放器主界面概述15</p><p> 5.2.2 主界面技術分析16</p><p> 5.3 歌曲列表17</p><p> 5.3.1 歌曲列表概述17</p><p> 5.3.2 歌曲列表實現(xiàn)17&
11、lt;/p><p> 5.4 網(wǎng)絡歌曲榜單界面18</p><p> 5.4.1網(wǎng)絡歌曲榜單界面概述18</p><p> 5.4.2 網(wǎng)絡歌曲榜單界面實現(xiàn)18</p><p> 5.5 歌曲詳情界面24</p><p> 5.5.1 歌曲詳情界面概述24</p><p> 5
12、.5.2 歌曲詳情界面實現(xiàn)25</p><p> 5.6 歌曲播放界面26</p><p> 5.6.1 歌曲播放界面概述26</p><p> 5.6.2 歌曲播放界面實現(xiàn)26</p><p> 5.6.3 歌詞顯示26</p><p> 5.7 歌曲播放29</p><p&
13、gt; 5.7.1 Service簡介29</p><p> 5.7.2播放服務PlayService實現(xiàn)31</p><p> 5.8 播放控制34</p><p> 6. 系統(tǒng)測試37</p><p> 6.1 掃描音樂測試37</p><p> 6.2 播放音樂測試37</p>
14、<p> 6.3 切歌測試38</p><p> 6.4 搜索歌曲測試39</p><p><b> 總結(jié)40</b></p><p><b> 致謝41</b></p><p><b> 參考文獻42</b></p><p
15、><b> 1. 概述</b></p><p><b> 1.1 項目背景</b></p><p> 在大學前三學年的學習生活中,我學會了C++、C#、Java這三門編程語言,正因為掌握了編程的基礎,于是在大學第四學年中,我自學了Android開發(fā),轉(zhuǎn)眼就要畢業(yè)了,我想要用我所學到的知識去完成一個基于Android的音樂播放器開發(fā)來
16、給我的大學畫上一個圓滿的句號。</p><p> 至于說為什么想到的會是一款基于Android的音樂播放器,我想說既然最近一學年在學習Android開發(fā),那就應該用現(xiàn)階段自己掌握得最熟練的技術去開發(fā)。至于為什么是音樂播放器,那就得說說音樂在平時生活中所占的比重了。</p><p> 音樂已經(jīng)成為了人們生活中不可或缺的一部分了,閑暇無聊時聽一首安靜的慢歌、朋友聚會時在KTV高歌一曲,聽歌
17、成了習慣后,軟件開發(fā)商發(fā)現(xiàn)了商機。各式各樣的手機音樂播放器隨之被推出。誠然,作為專業(yè)的軟件應用開發(fā)商所開發(fā)的產(chǎn)品功能還是很強大的,不管是在音樂資源還是界面效果上都是很符合大眾口味的。然而秉著虛心學習的態(tài)度,都不能抑制我想要開發(fā)一款屬于自己的音樂播放器的想法。</p><p> 1.2 國內(nèi)外相關研究現(xiàn)狀及發(fā)展趨勢</p><p> 目前國內(nèi)較為流行的幾款手機端音樂播放器主要有:網(wǎng)易云
18、音樂、酷狗音樂、酷我音樂、多米音樂、蝦米音樂、天天動聽等,這些播放器大都有海量的曲庫支持,專業(yè)的音效,炫酷的皮膚,詳細的歌曲信息、專輯信息等等。因這些播放器功能大都雷同,因本次所開發(fā)的播放器使用了百度音樂提供的開放接口,所以此處僅以百度音樂為例介紹其特點:</p><p> 百度音樂Android版是一款專為手機定制的功能強大的音樂播放器,數(shù)量龐大的音樂資源提供試聽下載,權威的推薦音樂榜單,新鮮的新歌推送,智能
19、語音搜歌,登錄賬號收藏音樂,PC端和手機即可同步顯示。</p><p> 而對于國外的音樂播放器,因為接觸得少,這里只介紹一款。</p><p> Beoplayer,是一款丹麥的音樂播放器,Beoplayer是一款免費軟件,由丹麥的Bang & Olufsen公司所設計開發(fā),這是一家全球頂級的數(shù)字設備產(chǎn)品提供商,他們的產(chǎn)品設計理念是“獨特高貴”,因此其公司的產(chǎn)品一直被音樂愛好
20、者所喜愛。</p><p> 1.3 項目研究意義</p><p> 作為即將畢業(yè)的大學生,畢業(yè)設計是對大學學習過程中知識積累量的一次考驗,而我也想知道在大學四年期間我到底有什么收獲,所以我想要通過這次的畢業(yè)設計課題“基于Android的音樂播放器”來面對這場考驗,并以一個令人滿意的成績完成考驗。</p><p> 1.4 本文主要內(nèi)容</p>
21、<p> 本次項目的主要研究內(nèi)容是研究、分析和實現(xiàn)基于Android手機平臺的音樂播放器,具體包括以下幾個部分:</p><p> ?。?)第一章介紹項目背景和國內(nèi)外現(xiàn)狀</p><p> ?。?)第二章介紹Android平臺的歷史和開發(fā)環(huán)境的搭建</p><p> ?。?)第三章介紹對播放器的需求分析</p><p> ?。?/p>
22、4)第四章介紹數(shù)據(jù)庫的設計</p><p> ?。?)第五章介紹項目詳細的設計</p><p> (6)第六章介紹系統(tǒng)測試</p><p> 2. Android開發(fā)環(huán)境搭建</p><p> Android Studio是Google推出的Android開發(fā)工具,基于IntelliJ IDEA開發(fā),類似于Eclipse等開發(fā)工具,An
23、droid Studio集成了Android開發(fā)工具用于開發(fā)和調(diào)試,并且在Android Studio的安裝包中已經(jīng)封裝了Android SDK,所以只需要安裝Java JDK 和 Android Studio即可開始Android應用的開發(fā)。在本次開發(fā)中,所采用的開發(fā)工具及其下載地址如下表1-1所示。</p><p> 表1-1 Android開發(fā)所需工具軟件版本信息及下載地址</p><
24、p> 將上述工具下載,首先安裝Java JDK,安裝完成后配置環(huán)境變量的Path路徑和classPath路徑,打開cmd命令行工具,輸入java和javac命令查看是否配置成功。</p><p> 安裝Android Studio時,若本機上并沒有Android SDK,需要勾選上Android SDK項,在安裝完畢以后需要打開Android SDK并選在一些必須的Android API,只有這樣才能使
25、Android Studio成功編譯Android項目。</p><p> 完成以上步驟,便可開始Android應用的開發(fā)了。</p><p><b> 3. 項目需求分析</b></p><p><b> 3.1 目的</b></p><p> 開發(fā)一款屬于自己的個性化的音樂播放器。<
26、;/p><p><b> 3.2 系統(tǒng)背景</b></p><p> 市場上各式各樣的播放器讓人眼花繚亂,讓人選擇起來卻無從下手。本著學習交流的心態(tài),在覺得自己有這種能力的情況下,開發(fā)一款自己的個性化的音樂播放器。</p><p><b> 3.3 問題說明</b></p><p> 音樂播放器
27、是手機必不可少的一部分,一個好的播放器能極大的增加用戶體驗,同時,界面簡潔,操作快捷也是一個播放器所應具備的。本播放器系統(tǒng)流程圖如圖3.1所示。</p><p><b> 3.4 系統(tǒng)范圍</b></p><p> 音樂播放器主要為用戶提供播放音頻文件的功能,文件范圍不限于本地文件,可播放或下載網(wǎng)絡歌曲文件,適合所有喜愛音樂的人群使用。</p>&l
28、t;p> 3.5 用例圖及用例描述</p><p> 用例圖如圖3.2所示。</p><p><b> 圖3.1系統(tǒng)流程圖</b></p><p><b> 圖3.2系統(tǒng)用例圖</b></p><p> 音樂播放器的用例詳情描述如下:</p><p> 用例
29、名稱:獲取本地歌曲列表。</p><p><b> 參與者:系統(tǒng)。</b></p><p> 目標:第一次使用系統(tǒng)時系統(tǒng)自動獲取本地符合條件歌曲的信息并存入數(shù)據(jù)庫,并生成歌曲列表供用戶選擇。</p><p> 基本事件流:打開播放器,播放器在歡迎界面中判斷是否初次使用本系統(tǒng)。</p><p> 用例名稱:獲取網(wǎng)絡
30、歌曲列表。</p><p><b> 參與者:用戶。</b></p><p> 目標:獲取百度音樂提供的各類型的歌曲榜單,方便用戶收聽或下載。</p><p> 基本事件流:用戶打開“發(fā)現(xiàn)”欄目,選擇對應的榜單,系統(tǒng)請求服務器返回歌曲信息并以列表形式返回給用戶。</p><p><b> 用例名稱:播放
31、。</b></p><p><b> 參與者:用戶。</b></p><p> 目標:播放用戶選定的歌曲。</p><p> 基本事件流:用戶在歌曲列表中選擇某項,系統(tǒng)在后臺開始播放與該項對應的歌曲。</p><p> 用例名稱:播放界面。</p><p><b>
32、 參與者:用戶。</b></p><p> 目標:用戶打開對應的歌曲的播放界面。</p><p> 基本事件流:用戶打開播放界面,系統(tǒng)顯示當前播放歌曲的詳細信息和播放進度。</p><p><b> 3.6 功能摘要</b></p><p> 軟件詳細功能如表3-1所示。</p><
33、;p><b> 表3-1功能摘要</b></p><p><b> 3.7 假定與約束</b></p><p> 運行環(huán)境約束詳情如表3-2所示。</p><p> 表3-2運行環(huán)境約束</p><p><b> 4. 數(shù)據(jù)庫設計</b></p>
34、<p> 4.1 數(shù)據(jù)庫概念設計</p><p> 根據(jù)上一章節(jié)所描述的需求分析可得到本播放器中所要使用的數(shù)據(jù)庫實體為“歌曲”,且歌曲信息實體包括歌曲id、名稱、演唱者、專輯、歌詞路徑、歌曲路徑、歌曲專輯圖片等屬性,其中歌曲id為數(shù)據(jù)表的主鍵。歌曲信息實體E-R圖如圖4.1所示。</p><p> 圖4.1 歌曲E-R圖</p><p><b&
35、gt; 4.2 數(shù)據(jù)表設計</b></p><p> 在對歌曲信息實體分析以后,就需要開始進行數(shù)據(jù)庫表的設計了。在本播放器中,需要進行保存在數(shù)據(jù)庫中的信息主要有“本地歌曲”、“最近下載任務”、“最愛歌曲”、“最近播放的歌曲”,而“最愛歌曲”已經(jīng)在“本地歌曲”中設置屬性判斷,無需再創(chuàng)建數(shù)據(jù)表,所以本播放器中供需使用三個表:本地歌曲表tb_local、下載任務表tb_download、最近播放表tb_
36、lately。</p><p> 本地歌曲表tb_local</p><p> tb_local表用來負責存儲由用戶掃描出的音樂文件信息,信息包括由系統(tǒng)自動生成的歌曲編號,從歌曲文件中解析出的相關信息,具體字段定義見表4-1。</p><p> 表4-1 tb_local表字段</p><p> 下載任務表tb_download<
37、;/p><p> tb_download負責保存用戶下載的歌曲信息,因歌曲下載完畢后會將信息轉(zhuǎn)存到tb_local表中,所以在tb_download中僅保存了歌曲編號信息,這個編號是從百度音樂接口獲取的歌曲編號。tb_download字段定義如表4-2所示。</p><p> 表4-2 tb_download表字段</p><p> 最近播放表tb_lately&
38、lt;/p><p> tb_lately負責保存用戶最近播放的15首歌曲,因播放的可能會是來源于網(wǎng)絡的歌曲,所以此表中也會保存如tb_local中除卻favorite的其他信息。字段定義如表4-3所示。</p><p> 表4-3 tb_lately字段</p><p> 4.3 數(shù)據(jù)庫的連接及操作類的編寫</p><p> 在數(shù)據(jù)庫連接
39、及操作類中,主要包括對數(shù)據(jù)庫的連接及對數(shù)據(jù)庫的增刪修改操作,要連接到SQLite數(shù)據(jù)庫,需要自定義工具類去繼承SQLiteOpenHelper抽象類,并實現(xiàn)其方法。此處先貼出代碼再做介紹。</p><p> public class DataBaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME =
40、"music.db"; private static final int VERSION = 1; public DataBaseHelper(Context context){ this(context,DATABASE_NAME,null,VERSION); } public DataBaseHelper(Context context,String name,SQ
41、LiteDatabase.CursorFactory cursorFactory,int version){ super(context,name,cursorFactory,version); } @Override public void onCreate(SQLiteDatabase db) { db.exec</p><p> 在DatabaseH
42、elper類中,通過實現(xiàn)構造方法去創(chuàng)建數(shù)據(jù)庫,然后在onCreate方法中執(zhí)行創(chuàng)建表的語句,當進行應用更新時,再在onUpgrade方法中進行更新數(shù)據(jù)庫的操作。然而到此還并沒有完成數(shù)據(jù)庫的連接。</p><p> 可以看到,在構造方法中使用到了Context對象,可以想到要連接到數(shù)據(jù)庫,就需要傳入這個Context對象,這就需要在Activity中對該數(shù)據(jù)庫連接對象進行實例化了。同時,為了使代碼更加簡潔,此處將
43、數(shù)據(jù)庫的其他操作方法寫到另一個操作類MyDatabase中。</p><p> 在MyDatabase中,通過實例化DataBaseHelper對象dbHelper,調(diào)用其父類中的方法getWiteableDatabase獲取一個SQLiteDatabase實例,通過這個實例的方法就可以進行數(shù)據(jù)庫的增刪修改操作了。</p><p><b> 查詢操作</b><
44、;/p><p> 在本播放器中,并沒有針對某項數(shù)據(jù)進行查詢,而是查詢某表中所有的歌曲信息并保存到一個游標集Cursor中,然后可通過此表中所擁有的字段再獲取一個信息集合List。下面代碼為根據(jù)表名稱獲取一個Cursor對象。</p><p> public Cursor getTable(String tableName){ SQLiteDatabase db = dbHelper
45、.getReadableDatabase(); return db.query(tableName, null, null, null, null, null, null);}</p><p><b> 插入操作</b></p><p> 此處僅以向本地歌曲表中插入一項數(shù)據(jù)為例介紹如何插入數(shù)據(jù)。要向本地歌曲表中插入數(shù)據(jù),需要傳入一個Music對象,并獲取
46、SQLiteDatabase的可寫對象,然后執(zhí)行此對象的insert方法即可,代碼如下:</p><p> public long insertToSong(String tableName,Music music){ SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentVal
47、ues(); values.put(MyMusicTable.SONG_ID,music.getSong_id()); values.put(MyMusicTable.URL,music.getUrl()); values.put(MyMusicTable.TITLE,music.getTitle()); values.put(MyMusicTable.ARTIST,music.getArtist());
48、 values.put(MyMusicTable.ARTIST_ID,music.getArtist_id()); values.put(MyMusicTable.ALBUM,music.getAlbum()); values.p</p><p><b> 更新操作</b></p><p> 要更新數(shù)據(jù)表中數(shù)據(jù),可直接調(diào)用SQLiteDat
49、abase對象的update方法。</p><p> public int update(String tableName,ContentValues cv,String whereClause,String[] args){ SQLiteDatabase db = dbHelper.getWritableDatabase(); return db.update(tableName,cv,whe
50、reClause,args);}</p><p> 其中tableName表示需要更新的表的名稱,cv表示一個鍵值對,其鍵為數(shù)據(jù)表中需要修改的字段,值則為更改后的值,whereClause等價于sql更新語句中的where條件,args數(shù)組表示whereClause中的“?”的值。</p><p><b> 刪除操作</b></p><p&g
51、t; 和更新操作一樣,要刪除某項數(shù)據(jù)可直接調(diào)用SQLiteDatabase對象的delete方法。</p><p> public int delete(String table,String whereClause,String[] args){ SQLiteDatabase db = dbHelper.getWritableDatabase(); return db.delete(tabl
52、e, whereClause, args);}</p><p><b> 5. 項目實現(xiàn)</b></p><p> 從本章節(jié)開始,便要逐步開始播放器系統(tǒng)代碼的編寫了,這其中包括界面UI的設計,各個功能的實現(xiàn)。但因代碼過多,此處便只貼出部分功能代碼,至于UI界面的設計等代碼,請查閱源文件。</p><p><b> 5.1 歡迎
53、界面</b></p><p> 5.1.1 歡迎界面概述</p><p> 一個應用是很需要一個歡迎界面的,一方面給用戶表明應用的性質(zhì),一方面又可在歡迎界面的顯示過程中去獲取應用配置信息。在本應用的歡迎界面SplashActivity中,通過顯示一張能夠表明主題的圖片的同時,去獲取應用的基本配置信息,如是否第一次打開應用,歌曲的播放模式,聯(lián)網(wǎng)方式,是否打開了搖一搖切歌等信息
54、。</p><p> 5.1.2 歡迎界面技術分析</p><p> 在執(zhí)行這些可能比較耗時的操作時,我們需要另開辟一個線程去執(zhí)行這些方法,在執(zhí)行完畢后,通過Handler的消息處理機制,發(fā)送消息給主線程去執(zhí)行接下來的操作。在這個另開辟的線程中執(zhí)行兩個方法,當啟動此應用時即開始執(zhí)行這個StartThread線程,其流程圖如圖5.1所示。部分代碼如下:</p><p&
55、gt; class StartThread implements Runnable{ @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
56、 open(); }}</p><p> 圖5.1 歡迎界面流程圖</p><p> 5.2 播放器主界面</p><p> 5.2.1 播放器主界面概述</p><p> 本應用的設計基本使用Activity和Fragment的方式進行界面的搭配,除卻歡迎界面SplashActivity,主界面MainActivity便
57、成了其它的Fragment的父容器。此外,為方便數(shù)據(jù)的統(tǒng)一使用,SplashActivity和MainActivity均繼承自自定義的BaseActivity,減少了代碼的冗雜量。主界面上功能流程圖如圖5.2所示。</p><p> 在MainActivity中,包括三個界面:頂部的導航界面,底部的當前播放信息界面,中部則是一個ViewPager組件,用于放置“我的”(LocalFragment)和“榜單”(N
58、etFragment)兩個Fragment。初始狀態(tài)下顯示“我的”界面,當點擊上方的“榜單”或向左滑動時,則可顯示網(wǎng)絡歌曲推薦榜單界面。主界面效果如圖5.3所示?!鞍駟巍苯缑嫒鐖D5.4所示。</p><p> 在主界面中可看到,LocalFragment通過一個GridView組件顯示播放器記錄的部分信息,通過讀取存于數(shù)據(jù)庫中的歌曲信息,在初始化GridView設置其適配器時將數(shù)據(jù)顯示于界面上。</p&g
59、t;<p> 5.2.2 主界面技術分析</p><p> 在本應用中,使用到了一個第三方的開源庫SlidingMenu,其效果是可展示一個側(cè)滑菜單,如常用的手機QQ的菜單樣式。通過使BaseActivity繼承其中的SlidingFragmentActivity,即可獲得這一個菜單對象,再在MainActivity的onCreate方法中初始化這個對象。效果如圖5.5所示。初始化menu的代碼
60、如下:</p><p> private void initMenu(){ menu = getSlidingMenu(); menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN); menu.setMode(SlidingMenu.LEFT); menu.setBehindOffsetRes(R.dimen.content_
61、width); menu.setShadowDrawable(R.drawable.shadow); menu.setShadowWidthRes(R.dimen.menu_shadow); MenuFragment menuFragment = new MenuFragment(); getSupportFragmentManager().beginTransaction().replace(R.i
62、d.container_menu, menuFragment).commit();}</p><p> 圖5-2 主界面功能流程圖</p><p> 圖5.3 播放器主界面圖 圖5.4 榜單界面圖 圖5.5 菜單界面</p><p><b> 5.3 歌曲列表</b></p><p
63、> 5.3.1 歌曲列表概述</p><p> 歌曲列表主要用于顯示用戶選擇的歌單的列表,如本地音樂、我的最愛、最近播放,界面包括上方的導航信息和其余部分的歌曲信息列表,當用戶點擊任何一首歌曲即可播放此歌曲,在每一項歌曲的列表項中都對應有菜單選項,用戶可根據(jù)所需對歌曲進行移除、查看詳情等操作。歌曲列表界面上的活動圖如圖5.6所示。</p><p> 5.3.2 歌曲列表實現(xiàn)&l
64、t;/p><p> 根據(jù)界面的樣式進行UI設計,在MusicListFragment中找出歌曲列表ListView,為了給單項歌曲增加菜單選項,我們需要自定義列表項的布局,然后在ListView的Adapter中給每個菜單項添加事件。此外,為了實現(xiàn)單機歌曲項播放歌曲,我們需要給這個ListView添加OnItemClick事件。除此之外,為了更方便的實現(xiàn)歌曲項中的菜單點擊事件,我們需要定義一個回調(diào)接口OnLocal
65、MusicListMenuClick,并使本界面對應的Fragment類MusicListFragment實現(xiàn)這個接口中的方法,界面截圖如5.7所示。</p><p> 圖5.6歌曲列表活動圖 圖5.7 歌曲列表界面</p><p> 5.4 網(wǎng)絡歌曲榜單界面</p><p> 5.4.1網(wǎng)絡歌曲榜單界面概述</
66、p><p> 網(wǎng)絡歌曲榜單界面NetFragment主要用來顯示由百度音樂提供的網(wǎng)絡歌曲熱門榜單,如圖5.8所示,因其接口提供數(shù)據(jù)有限,本播放器僅提供了圖左側(cè)的的部分推薦榜單,右側(cè)則用于顯示對應榜單的前50首歌曲,同樣,這也是播放器主界面的內(nèi)容,是主界面布局中的ViewPager的一個Fragment。</p><p> 圖5.8 網(wǎng)絡歌曲榜單</p><p>
67、5.4.2 網(wǎng)絡歌曲榜單界面實現(xiàn)</p><p> 因為在NetFragment的界面中同樣是在兩側(cè)各放置一個Fragment并實現(xiàn)回調(diào)接口,所以需要在NetFragment的布局文件中為這兩個Fragment留出空間以便于放置。此處就介紹這兩個Fragment:ListMenuFragment 和ListFragment。</p><p> 榜單選項界面ListMenuFragmen
68、t</p><p> 此Fragment內(nèi)容相對簡單,僅需要在布局中放置所需的按鈕并添加相應的點擊事件即可,為提高代碼的簡潔性,特為此類聲明了一個回調(diào)接口,以便在NetFragment中直接調(diào)用這些方法,接口聲明如下:</p><p> public interface OnListMenuClickListener{ void onListMenuClick(View vie
69、w); }</p><p> 在接口的onListMenuClick方法中傳入一個View參數(shù),在NetFragment中根據(jù)此View的ID判斷是點擊了哪個按鈕,并執(zhí)行相應的事件方法,方法代碼如下:</p><p> public void onListMenuClick(View view) { if (listFragment == null)return; s
70、witch (view.getId()){ case R.id.btn_list_menu_newMusic: listFragment.updateList(GetMusicList.MUSIC_LIST_NET); break; case R.id.btn_list_menu_hotMusic: listFragment.upda
71、teList(GetMusicList.MUSIC_LIST_HOT); break; case R.id.btn_list_menu_europeMusic: listFragment.updateList(GetMusicList.MUSIC_LIST_EUROPE); break; </p><p>
72、下面為ListFragment中的updateList方法:</p><p> public void updateList(int i) { this.type = i; if(activity.isNetworkAvailable()){ txt_loading.setVisibility(View.VISIBLE); new GetNetMusicsTask
73、().execute(i); } }</p><p> 可以看到,當傳入一個類型參數(shù)時,就會開始執(zhí)行一個GetNetMusicsTask的異步任務,在此任務中會從網(wǎng)絡獲取一段xml數(shù)據(jù),并在獲取以后解析xml數(shù)據(jù)并生成一個ArrayList<QueryResult>對象,異步任務類代碼如下:</p><p> class GetNetMusicsTask ext
74、ends AsyncTask<Integer, Integer, ArrayList<QueryResult>> { @Override protected ArrayList<QueryResult> doInBackground(Integer... params) { ArrayList<QueryResult> resultArrayList = n
75、ew ArrayList<>(); switch (params[0]) { case GetMusicList.MUSIC_LIST_NEW: GetMusicList.getMusicList(GetMusicList.MUSIC_LIST_NET, 50, 0, resultArrayList); break;
76、 case GetMusicList.MUSIC_LIST_HOT: GetM</p><p> 其中解析xml數(shù)據(jù)時用到了一種非常流行的Jsoup處理xml文檔的方式,Jsoup是一款基于Java的HTML解析器,可直接解析某個URL地址、HTML、XML文本內(nèi)容,它提供了一套非常省時省力的API,可通過DOM、CSS以及類似于JQuery的操作方法直接取出或
77、操作數(shù)據(jù)。下面是本播放器解析榜單XML文本的方法。</p><p> public static void getMusicList(int type,int size,int offset,ArrayList<QueryResult> results){ String url = BASE_URL + "baidu.ting.billboard.billList&type
78、="+type+"&size="+size+"&offset="+offset; Document doc = null; try { doc = Jsoup.connect(url).timeout(5000).get(); Elements songs = doc.select("song_list"
79、).select("song"); if(results == null){ results = new ArrayList<>(); }else{ results.clear(); } for(Element son</p><p> 榜單歌曲列表界面ListFra
80、gment</p><p> 如同歌曲列表界面MusicListFragment,本界面也同樣是實時改變此界面中的ListView的Adapter達到改變項數(shù)據(jù),所以需要為ListView的每個項設置布局并設計其項上的點擊事件,而點擊的目的是打開對應歌曲的詳情頁面,代碼如下:</p><p> listView.setOnItemClickListener(new AdapterVie
81、w.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { QueryResult result = (QueryResult) parent.getAdapter().getItem(position); activity.in
82、itDetailFragment(result.getSongID()); }});</p><p> 5.5 歌曲詳情界面</p><p> 5.5.1 歌曲詳情界面概述</p><p> 歌曲詳情界面主要用來展示用戶所選擇的歌曲的詳細信息,包括歌曲名、歌手、所在專輯、年份、歌詞等信息,若歌曲為網(wǎng)絡資源文件還可進行下載操作。頁面效果如圖5.10所示
83、。</p><p> 圖 5.10 歌曲詳情界面</p><p> 5.5.2 歌曲詳情界面實現(xiàn)</p><p> 在歌曲詳情界面DetailFragment中,需要有一個ImageView來加載專輯圖片,多個TextView來顯示相關的文本信息,在DetailFragment中,為不影響主線程的進行,需要另開啟異步任務去加載專輯圖片、歌詞文本等信息,在獲取歌
84、詞的異步任務中的DoInBackground方法代碼如下:</p><p> protected Bitmap doInBackground(Long... params) { xml = GetMusicInfo.getMusicDownloadInfo(songID); if(bitrates != null){ bitrates.clear(); } bit
85、rates = GetMusicInfo.getMusicBitrateList(xml); if(bitrates == null){ music = GetMusicInfo.getMusicInfoFromPlayInterface(songID); hasBitrate = false; }else{ music = GetMusicInfo.getMusicInf
86、o(xml, bitrates.get(0)); hasBitrate = true; } Bitmap bitmap = null; if (music.getAlbumImage(</p><p> 5.6 歌曲播放界面</p><p> 5.6.1 歌曲播放界面概述</p><p> 作為一個音樂播放器,當然需要一
87、個歌曲播放時的詳細信息界面,界面主要展示歌曲名、歌手、專輯圖片、歌詞以及對歌曲的播放控制等控件。如圖5.11所示。</p><p> 圖5.11 播放界面</p><p> 5.6.2 歌曲播放界面實現(xiàn)</p><p> 如圖5.11所示,較之前面所介紹的頁面不同的是,本頁面有更多的組件,設計更復雜的UI布局。首先在頁面頂部是一個返回按鈕,以及歌曲的名稱和歌手
88、的文本組件;在界面中部則是歌詞和歌曲專輯圖片(截圖中未顯示),當在屏幕上左劃或右劃則交替顯示專輯圖片或歌詞;在頁面底部,則是當前歌曲的播放控制的按鈕:播放進度、播放模式、上一曲、播放暫停、下一曲、音量按鈕。關于更詳細的布局,請查看源文件中l(wèi)ayout中的fragment_play2.xml文件。</p><p> 5.6.3 歌詞顯示</p><p> 本播放器實現(xiàn)了歌曲播放時歌詞的同
89、步顯示,但由于Android官方并沒有提供類似的組件,且網(wǎng)絡上對歌曲歌詞文件的類型又各有不同,所以本播放器中采用自定義組件的方式來實現(xiàn)歌詞的顯示。</p><p> 不同的播放器可能采用不同格式的歌詞文件,在本播放器中則采用后綴為lrc的歌詞文件作為解析源頭,當然,在解析之前我們需要先把歌詞組件定義出來,在Android中,自定義組件需要繼承所有組件的父類View或者其子類,此處則是繼承的父類View,同時實現(xiàn)
90、父類的構造方法。</p><p> public class Lrc extends View { private Scroller scroller; private OnLrcClickListener onLrcClickListener; public void setOnLrcClickListener(OnLrcClickListener onLrcClic
91、kListener){ this.onLrcClickListener = onLrcClickListener; } public Lrc(Context context) { super(context); scroller = new Scroller(context); init(); } public Lrc(
92、Context context, AttributeSet attrs) { super(context, attrs); scroller = ne</p><p> 因為需要在布局文件中用到自定義的Lrc組件,且需要為Lrc中的文本設置字體大小,所以需要在attr.xml中聲明組件的這個屬性。</p><p> <resources>
93、 <declare-styleable name="Lrc"> <attr name="textSize" format="dimension"></attr> </declare-styleable></resources></p><p> 在Lrc中,對于一
94、個String類型的ArrayList集合,我們需要分別在onDraw方法中繪制這些String,對于當前正在播放的歌詞我們需要定義一個畫筆hPaint,對于其他歌詞需要定義一個畫筆nPaint,當然這兩個畫筆對象只是以不同顏色的區(qū)別來突出顯示當前正在播放的歌詞</p><p> hlPaint = new Paint();hlPaint.setAntiAlias(true);hlPaint.setText
95、Align(Paint.Align.CENTER); nPaint = new Paint();nPaint.setTextAlign(Paint.Align.CENTER);nPaint.setAntiAlias(true);</p><p> 在歌詞繪制時,需要用到當前組件的高度和寬度,通過實現(xiàn)父類的onSizeChanged方法可獲取。</p><p> protected
96、 void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.width = w; this.height = h;}</p><p> 到此,則可以開始繪制歌詞了,為了不多余繪制,僅在當前高度和寬度范圍內(nèi)繪制相應歌詞,下面為onDraw方法中部分代
97、碼。</p><p> canvas.drawText(listList.get(index).getLyc(), width / 2, height / 2, hlPaint);float temp = height / 2; for (int i = index - 1; i >= 0; i--) { temp = temp - 2*textSize; if (temp >
98、0) canvas.drawText(listList.get(i).getLyc(), width / 2, temp, nPaint);}temp = height / 2; for (int i = index + 1; i < listList.size(); i++) { temp = temp + 2*textSize; if(temp < height) {
99、 canvas.drawText(listList.get(i).getLyc(), width / 2, temp, nPaint); }}</p><p> 當然,當沒有歌詞文件時,也需要繪制出相應的提示文本。nPaint.setColor(Color.RED);nPaint.setTextSize(textSize);canvas.drawText("找不到歌詞", wi
100、dth / 2, height/2, nPaint);</p><p><b> 5.7 歌曲播放</b></p><p> 在Android中,Android提供了一個MediaPlayer來播放多媒體文件,然而為了實現(xiàn)歌曲的后臺播放,我們不能再Activity中去播放媒體文件,而是通過Service去播放。</p><p> 5.7.
101、1 Service簡介</p><p> Service是Android系統(tǒng)中的四大組件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的級別差不多,但不能自己運行只能后臺運行,并且可以和其他組件進行交互。service可以在很多場合的應用中使用,比如播放多媒體的時候用戶啟動了其他Activity這個時候程序要在后臺繼續(xù)播放,比如
102、檢測SD卡上文件的變化,再或者在后臺記錄你地理信息位置的改變等等,總之服務總是藏在后臺的。</p><p> 如圖5.12所示,Service的啟動方式有兩種,一種是通過Context對象的startService方法,另一種則是通過Context的bindService方法,因本播放器采用的是第二種方式,則僅介紹此種方式。</p><p> 從圖中可看到,通過bindService方
103、法啟動Service的流程為:context.bindService()->onCreate()->onBind()->Servicerunning->onUnbind()->onDestroy()->Service stop</p><p> onBind()將返回給客戶端一個IBind接口實例,IBind允許客戶端回調(diào)服務的方法,比如得到Service的實例、運行狀態(tài)或其
104、他操作。這個時候把調(diào)用者(Context,例如Activity)會和Service綁定在一起,Context退出了,Srevice就會調(diào)用onUnbind->onDestroy相應退出。所以調(diào)用bindService的生命周期為:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。在Service每一次的開啟關閉過程中,只有onStart可被多次調(diào)
105、用(通過多次startService調(diào)用),其他onCreate,onBind,onUnbind,onDestory在一個生命周期中只能被調(diào)用一次。</p><p> 圖5.10 service啟動方式</p><p> 5.7.2 播放服務PlayService實現(xiàn)</p><p> 自定義PlayService類,繼承Service,添加一個繼承Binde
106、r的內(nèi)部類MyBinder,實現(xiàn)方法getPlayService返回當前PlayService對象。并聲明一個MyBinder對象。</p><p> public class PlayService extends Service {private final IBinder mBinder = new MyBinder();private final IBinder mBinder = new MyBi
107、nder();</p><p> public class MyBinder extends Binder{ public PlayService getPlayService(){ return PlayService.this; }}}</p><p> 在BaseActivity中初始化服務連接對象ServiceConnection。&l
108、t;/p><p> private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { PlayService.MyBinder binder = (PlayService.M
109、yBinder) service; mPlayService = binder.getPlayService(); } @Override public void onServiceDisconnected(ComponentName name) { mPlayService = null; isBind = false; }</p><
110、p><b> };</b></p><p> 然后通過綁定服務即可調(diào)用PlayService類中的方法了。</p><p> public void bindPlayService() { if (!isBind) { Intent intent = new Intent(this, PlayService.class);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于安卓android的mp3播放器的設計與實現(xiàn)-軟件工程畢業(yè)論文
- 基于android的mp3音樂播放器設計畢業(yè)設計論文
- 基于android的MP3播放器的設計與實現(xiàn)論文.doc
- 基于單片機的mp3播放器設計【畢業(yè)論文】
- 基于android的mp3播放器的設計與實現(xiàn)
- 給予android的mp3音樂播放器設計--畢業(yè)設計論文
- 基于mp3播放器的設計
- 畢業(yè)論文(設計)基于stm32的mp3播放器設計
- 基于安卓的音樂播放器開發(fā)-畢業(yè)論文
- 基于dsp的mp3播放器設計
- mp3播放器設計設計
- 軟件專業(yè)畢業(yè)論文--基于java的mp3播放器的設計與實現(xiàn)
- 畢業(yè)論文---基于單片機控制的mp3音樂播放器的設計
- 基于fpga的mp3音樂播放器設計
- 基于android的音樂播放器畢業(yè)論文
- 基于安卓android系統(tǒng)的多媒體播放器的開發(fā)功能實現(xiàn)畢業(yè)論文
- mp3播放器的實現(xiàn)開題報告
- 基于ZSP的MP3播放器SoC設計.pdf
- 基于linux的mp3播放器設計與實現(xiàn)
- 基于單片機的mp3播放器設計-畢業(yè)設計論文
評論
0/150
提交評論