基于android平臺的音樂播放器設(shè)計與實現(xiàn)畢業(yè)論文_第1頁
已閱讀1頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、<p><b>  XX學(xué)院</b></p><p>  本科畢業(yè)論文(設(shè)計)</p><p>  題 目 基于Android平臺的音樂播放器設(shè)計與實現(xiàn) </p><p>  院(系) 電子工程與電氣自動化學(xué)院 </p><p>  專 業(yè) 電氣工程及其自動化

2、 </p><p>  學(xué)生姓名 </p><p>  學(xué) 號 </p><p>  指導(dǎo)教師 職稱 </p><p>  論文

3、字?jǐn)?shù) 80000 </p><p>  完成日期: 年 月 日</p><p>  基于Android平臺的音樂播放器設(shè)計與實現(xiàn)</p><p><b>  摘 要</b></p><p>  Android是一種基于Linux的自由及開放源代碼的操作系

4、統(tǒng),其最大的優(yōu)勢就是顯著的開放性。開放的源碼吸引大量的開發(fā)者和手機(jī)開發(fā)商,開放的平臺帶來更大的競爭,讓更多的消費者能夠以低價位買到心儀的手機(jī)。隨著智能手機(jī)的普遍和Android應(yīng)用的日益豐富,一個嶄新的平臺也將走向成熟。</p><p>  本課題的目的就是開發(fā)出一款基于Android平臺,可以播放MP3歌曲文件的音樂播放器。播放器的界面新穎,功能豐富,操作方便。播放器主要從界面的設(shè)計著手,設(shè)計了歡迎界面、功能界

5、面、掃描界面、顯示歌曲列表界面,播放及顯示歌詞界面,實現(xiàn)了播放歌曲的基本功能,還有歌詞同步顯示、支持手勢切換、后臺播放歌曲,自動關(guān)閉播放器等功能。</p><p>  關(guān)鍵詞:Android;開放;音樂播放器</p><p>  Design and Implementation of Music Player </p><p>  Based on Android

6、 Platform</p><p><b>  Abstract</b></p><p>  Android is a free and open source Linux-based operating system with openness significantly. Open source attract a lot of developers and mo

7、bile manufacturers , an open platform can bring more greater competition, lead to more consumers to buy low-priced favorite phones. A new platform will be mature with smartphones widespreadly and Android applications ric

8、h increasingly. </p><p>  The purpose of this title is to develop a music player based on Android platform, that can play MP3 music files. The player has pretty UI(User Interface), abundant function, and eas

9、y to operate. It mainly start from the design of UI, design the welcome interface, function interface, scanning interface, display the songs list interface, play music and show lyrics interface, realized the basic playin

10、g function besides show lyrics synchronously, support for gestures to switch, play musics backgroun</p><p>  Key Words:Android, open, Music Player</p><p><b>  目 錄</b></p>&l

11、t;p><b>  第一章 緒論1</b></p><p>  1.1 研究背景及意義1</p><p>  1.2 研究內(nèi)容1</p><p>  第二章 Android應(yīng)用概述2</p><p>  2.1 創(chuàng)建Android應(yīng)用2</p><p>  2.2 項目目錄簡介2

12、</p><p>  第三章 播放器總體設(shè)計4</p><p>  3.1 播放器功能需求分析4</p><p>  3.2 播放器設(shè)計總體流程5</p><p>  第四章 播放器設(shè)計與實現(xiàn)6</p><p>  4.1 界面的設(shè)計6</p><p>  4.2 功能的實現(xiàn)7<

13、;/p><p>  4.2.1 動態(tài)圖片的實現(xiàn)7</p><p>  4.2.2 Adapter的實現(xiàn)8</p><p>  4.2.3 掃描文件的實現(xiàn)11</p><p>  4.2.4 數(shù)據(jù)存取的實現(xiàn)12</p><p>  4.2.5 手勢滑動的實現(xiàn)13</p><p>  4.2.

14、6 歌詞顯示的實現(xiàn)13</p><p>  4.2.7 播放歌曲的實現(xiàn)15</p><p>  第五章 播放器運行測試18</p><p><b>  參考文獻(xiàn)20</b></p><p><b>  致 謝21</b></p><p><b>  第一章

15、 緒論</b></p><p>  1.1 研究背景及意義</p><p>  Android,一種基于Linux的自由及開放源代碼的操作系統(tǒng)。2012年11月數(shù)據(jù)調(diào)查顯示,Android占有全世界智能手機(jī)操作系統(tǒng)76%的市場份額,而中國市場占有率達(dá)90%。隨著Android智能手機(jī)價格的平民化,那些功能不強,畫面單調(diào),鍵盤操作過時的塞班系統(tǒng)手機(jī)已經(jīng)逐漸被淘汰了。在Androi

16、d平臺開發(fā)應(yīng)用或游戲,前景廣闊,市場需求量大。以前落后的操作手機(jī)上所有能玩的,在Android平臺都能做到,而且做得更好,界面效果更炫,用戶體驗更佳。</p><p>  本項目是一款基于Android平臺的音樂播放器。這是一個對于開發(fā)者而言比較容易上手的項目,對于用戶來說是一個常用的應(yīng)用軟件。研究了多款音樂播放器應(yīng)用,積累了一定的圖片素材,借鑒了部分的布局設(shè)計,為本項目的開發(fā)做好充分準(zhǔn)備。本項目希望可以做到讓用

17、戶隨時隨地處于音樂旋律之中,獲得舒緩壓力,調(diào)整心情的最佳體驗。同時,使設(shè)計者更加熟練的使用Android技術(shù),積累開發(fā)項目的寶貴經(jīng)驗。</p><p><b>  1.2 研究內(nèi)容</b></p><p>  目前,Android手機(jī)音樂播放器技術(shù)雖然已經(jīng)成熟,但是用戶體驗并不很好,為用戶加載許多不必要圖片信息,植入一些煩人的廣告,浪費用戶流量。本項目制作的是一款簡約

18、而不簡單的音樂播放器,以下將是本項目需要深入研究的內(nèi)容:</p><p>  Android的界面添加動態(tài)圖片;</p><p>  編寫Sqlite數(shù)據(jù)庫語句存取用戶數(shù)據(jù);</p><p>  對播放器界面增加手勢的支持;</p><p>  關(guān)閉播放器界面后臺播放歌曲;</p><p>  播放界面同步顯示歌詞。&

19、lt;/p><p>  歌詞界面增加手勢改變播放進(jìn)度的功能。</p><p>  實現(xiàn)定時自動關(guān)閉播放器功能。</p><p>  第二章 Android應(yīng)用概述</p><p>  2.1 創(chuàng)建Android應(yīng)用</p><p>  新建一個Android項目,新建的項目信息如圖2-1所示:這是最新版ADT(Androi

20、d Development Tools)插件,版本21。如果ADT版本較低,界面是不同的。項目要求智能手機(jī)最低Android 2.2系統(tǒng)。</p><p>  圖2-1新建Android Project</p><p>  2.2 項目目錄簡介</p><p>  展開res目錄,如圖2-2所示。anim、drawable和raw默認(rèn)是沒有的。這是本項目需要新建的,

21、且文件夾的命名是固定的。res是resource的縮寫,里面存放許多資源文件,可以直接被我們在代碼中直接引用。anim主要存放動畫布局xml文件,drawable、drawable-hdpi、drawable-ldpi、drawable-mdpi和drawable-xhdpi都是存放圖片資源的,根據(jù)手機(jī)的分辨率的不同自動匹配使用什么樣的圖片。layout目錄是存放界面布局文件,values目錄存放字符串資源,顏色資源,尺寸大小資源等。&

22、lt;/p><p>  與res目錄功能類似的是assets目錄,但是assets文件夾是存放不進(jìn)行編譯加工的原生文件,即該文件夾里面的文件是不能直接引用的,可以存放一些圖片,html,js, css等文件。</p><p>  圖2-2 res目錄的層次</p><p>  如圖2-3所示,gen目錄是Android系統(tǒng)自己所維護(hù)的文件目錄,目錄下的R文件自動編譯生成

23、,自動更新修改。R文件是預(yù)編譯res目錄所生成的Java文件,如果在drawable-hdpi目錄下存放一張背景圖片splash_bg.png;那我們在Java代碼中引用這張圖片資源就是 R.drawable.splash_bg。</p><p>  圖2-3 gen目錄的層次</p><p>  4.如圖2-4所示,bin目錄里存放的是編譯好的二進(jìn)制文件,設(shè)計者只需要知道bin目錄里有這

24、個項目所生成的apk文件,可以直接安裝在手機(jī)上運行。</p><p>  圖2-4 bin目錄的層次</p><p>  5. 如圖2-5所示,src目錄存放設(shè)計者所寫的所有Java代碼,目錄里的文件夾都是每個類所在的包名,Java中包的概念就是給文件分類到不同的文件夾中。</p><p>  圖2-5 src目錄的層次</p><p>  

25、第三章 播放器總體設(shè)計</p><p>  3.1 播放器功能需求分析</p><p>  項目的設(shè)計流程通常是基于項目的功能來安排設(shè)計的。以下是播放器的功能需求分析:</p><p>  提供兩種掃描SDCard(手機(jī)內(nèi)存卡)中MP3歌曲文件的方式,一鍵掃描所有存在的歌曲文件和用戶指定文件夾進(jìn)行掃描。</p><p>  掃描完成后,歌曲自

26、動分類,保存到Sqlite數(shù)據(jù)庫。Menu菜單提供重新掃描的功能,方便用戶再次掃描。</p><p>  “本地音樂”界面中可以添加或者移除最愛歌曲,添加音樂到“播放列表”,在“播放列表”中移除歌曲。</p><p>  播放歌曲設(shè)定,暫停和改變播放進(jìn)度。選擇上一首,下一首,改變播放的模式(順序播放,單曲循環(huán),全部循環(huán),隨機(jī)播放)。</p><p>  主界面時,手

27、指滑動屏幕,就可以跳到顯示歌詞界面,在顯示歌詞界面中能同步顯示歌詞,手指滑動屏幕,改變播放進(jìn)度。隱藏播放器界面,后臺播放歌曲。通知欄顯示播放曲目。</p><p>  提供自動關(guān)閉播放器的功能。當(dāng)用戶點擊Menu中彈出的“睡眠”菜單,選擇多長時間后關(guān)閉,播放器會自動關(guān)閉。</p><p>  本播放器在界面上做了一個嘗試性的創(chuàng)新,讓界面顯示一張動態(tài)圖片,(android系統(tǒng)不能直接顯示.g

28、if動態(tài)圖片的)。</p><p>  3.2 播放器設(shè)計總體流程</p><p>  Step1:歡迎界面</p><p>  準(zhǔn)備好raw文件下的音頻文件播放音樂;在布局文件中定義一個ImageView控件,用Handler控制顯示不同圖片,形成gif動畫效果;然后用Handler控制不同背景圖片的顯示。</p><p>  Step2:

29、功能主界面</p><p>  主界面的布局文件內(nèi)容:在頂部顯示動態(tài)圖片,底部顯示播放控制的控件,中間顯示未知,是可變的區(qū)域,用于顯示功能菜單、歌曲列表等內(nèi)容的區(qū)域。</p><p>  Step3:選擇掃描方式界面</p><p>  顯示兩個Button按鈕控件,監(jiān)聽器事件不同。點擊自定義掃描,跳轉(zhuǎn)到另一個Activity界面,用戶指定文件夾掃描的界面</

30、p><p>  Step4:自定義掃描界面</p><p>  顯示手機(jī)內(nèi)存卡可以操作的文件夾目錄層次,用戶點擊CheckBox單選框選擇掃描,出現(xiàn)掃描按鈕,點擊掃描。顯示目錄層次用ListView,需要編寫合適的Adapter。Adapter含有CheckBox事件監(jiān)聽器。掃描歌曲完成后,需要對歌曲信息分類,然后創(chuàng)建表來保存數(shù)據(jù),需要編寫Sqlite數(shù)據(jù)存儲業(yè)務(wù)邏輯代碼。</p>

31、<p>  Step5:顯示歌曲界面</p><p>  掃描完成后,顯示歌曲界面??梢杂猛粋€ListView,但需要編寫不同的Adapter。</p><p>  顯示“本地歌曲”的Adapter需要有添加最愛歌曲和添加到“播放列表”兩個按鈕;</p><p>  顯示“播放列表歌曲”需要有移除歌曲按鈕;顯示其他歌曲界面不需要其他按鈕。</p

32、><p>  Step6:播放歌曲</p><p>  編寫Service類,可以后臺播放歌曲。用Handler控制SeekBar進(jìn)度的更新。</p><p>  暫停、上一首、下一首、播放模式的控制全部由Service來完成。</p><p>  Step7:顯示歌詞</p><p>  用IO流讀取lrc文件,分別讀取

33、時間和內(nèi)容。然后用Handler不斷的更新顯示的歌詞位置。手勢滑動,獲取滑動距離,換算成時間,改變播放進(jìn)度。</p><p>  Step8:Menu界面和功能</p><p>  Menu采用PopupWindow彈出菜單,功能有掃描,睡眠,退出,重新掃描即清空數(shù)據(jù)庫信息,定時關(guān)閉使用線程檢測是否到達(dá)指定時間,退出功能需要關(guān)閉數(shù)據(jù)庫,關(guān)閉Service,finish Activity。&

34、lt;/p><p><b>  播放器設(shè)計與實現(xiàn)</b></p><p><b>  4.1 界面的設(shè)計</b></p><p>  Android應(yīng)用開發(fā)中在res/layout目錄中編寫xml文件來設(shè)計界面。如圖4-1是第一個界面,也是播放器的歡迎界面,在LinearLayour布局中使用ImageView控件,不斷改變I

35、mageView顯示的圖片,形成動態(tài)效果。</p><p>  圖4-1 播放器歡迎界面</p><p>  如圖4-2所示是歡迎界面跳轉(zhuǎn)之后的功能主界面。頂部顯示動態(tài)圖片,中間顯示了功能清單,底部顯示播放歌曲控制的控件。</p><p>  接著需要編寫用戶掃描歌曲的界面,如圖4-3所示。選擇掃描方式的界面提供給用戶兩個Button。掃描歌曲完成后需要顯示歌曲列表

36、,這是需要用ListView搭配合適的適配器Adapter來實現(xiàn)的,關(guān)于Adapter的使用后面論述。</p><p>  Android任何功能實現(xiàn)的基礎(chǔ)都是良好的界面,界面的好壞直接影響到用戶的好感度,所以對于Android應(yīng)用的開發(fā),尤其要注意界面的開發(fā)。如今大多數(shù)應(yīng)用的版本升級,做的基本上都是設(shè)計更好的界面贏得更多用戶的青睞。</p><p>  圖4-2 播放器主界面</p

37、><p>  圖4-3 選擇掃描方式 </p><p><b>  4.2 功能的實現(xiàn)</b></p><p>  4.2.1 動態(tài)圖片的實現(xiàn)</p><p>  動態(tài)圖片需要在drawable目錄下,新建xml文件,根元素是level-list。代碼如下:有多少幀圖片對于編寫多少個item。</p><

38、;p>  <?xml version="1.0" encoding="utf-8"?></p><p>  <level-list xmlns:android="http://schemas.android.com/apk/res/android" ></p><p>  <item andr

39、oid:drawable="@drawable/logo_anim_01" android:maxLevel="1" /></p><p>  <item android:drawable="@drawable/logo_anim_02" android:maxLevel="2" /></p>&

40、lt;p>  <item android:drawable="@drawable/logo_anim_03" android:maxLevel="3" /></p><p>  </level-list></p><p>  在代碼中用Handler控制,主要邏輯代碼如下:</p><p> 

41、 private int level = 0;</p><p>  //定義一個變量,控制顯示第幾張圖片,值與android:maxLevel的值對應(yīng)。</p><p>  private Handler mHandler = new Handler() {</p><p>  public void handleMessage(android.os.Message

42、 msg) {</p><p>  if (msg.what == -1) {</p><p>  level++;// 自增</p><p>  if (level == 50) {</p><p>  //停止顯示動畫,進(jìn)行下一步操作。</p><p><b>  } else {</b>&l

43、t;/p><p>  anim_imageview.getDrawable().setLevel(level); / 不斷的切換下一張圖片</p><p>  sendEmptyMessageDelayed(-1, 100); //圖片切換間隔時間為100ms</p><p><b>  }</b></p><p><

44、b>  } </b></p><p>  在onCreate方法中執(zhí)行mHandler.sendEmptyMessage(-1);那么就會立即執(zhí)行Handler中的handleMessage方法,匹配msg.what == -1的代碼塊執(zhí)行。然后再sendEmptyMessageDelayed(-1, 100); 表示延時100ms繼續(xù)執(zhí)行msg.what == -1的代碼塊,類似于一種循環(huán)的效

45、果。</p><p>  4.2.2 Adapter的實現(xiàn)</p><p>  安卓應(yīng)用絕大多數(shù)情況需要使用到ListView控件,而顯示ListView控件就通常需要編寫合適的Adapter。Adpter的作用就是告訴ListView控件每個Item布局(子布局)顯示什么,怎樣顯示。所以編寫一個Adpter,首先編寫Item布局顯示的內(nèi)容。</p><p>  下

46、面是一個Adapter的核心代碼,實現(xiàn)效果如圖4-4所示。</p><p>  public class ListingMusicAdapter extends BaseAdapter {</p><p>  private Context mContext; </p><p>  private List<Music> listingMusics; /

47、/播放列表中的歌曲</p><p>  public ListingMusicAdapter(Context mContext,List<Music> listingMusics) {</p><p>  this.mContext = mContext;</p><p>  this.listingMusics = listingMusics;<

48、;/p><p><b>  }</b></p><p>  public int getCount() {</p><p>  return listingMusics.size(); // 返回個數(shù)對應(yīng)顯示子布局的個數(shù)</p><p><b>  }</b></p><p> 

49、 public Object getItem(int position) {</p><p>  return listingMusics.get(position);</p><p><b>  }</b></p><p>  public long getItemId(int position) {</p><p>

50、  return position;</p><p><b>  }</b></p><p>  // Adpter的編寫,重點是需要重寫getView方法。</p><p>  public View getView(final int position, View convertView, ViewGroup parent) {</p

51、><p>  ViewHolder holder = null;</p><p>  if (null == convertView) {</p><p>  convertView = LayoutInflater.from(mContext).inflate(R.layout.list_musics_item, null);</p><p>

52、  holder = new ViewHolder();</p><p>  holder.music_count = (TextView) convertView.findViewById(R.id.listing_music_seq);</p><p>  holder.music_name = (TextView) convertView.findViewById(R.id.list

53、ing_music_name);</p><p>  holder.music_singer = (TextView) convertView.findViewById(R.id.listing_singer);</p><p>  holder.subLay = (LinearLayout) convertView.findViewById(R.id.listing_sub_layout

54、);</p><p>  convertView.setTag(holder);</p><p><b>  } else {</b></p><p>  holder = (ViewHolder) convertView.getTag();</p><p><b>  }</b></p>

55、;<p>  holder.music_count.setText((position + 1) + "");</p><p>  holder.music_name.setText(listingMusics.get(position).getMusic_name());</p><p>  holder.music_singer.setText(lis

56、tingMusics.get(position).getSingername());</p><p>  holder.subLay.setOnClickListener(new View.OnClickListener() {</p><p>  public void onClick(View v) {</p><p>  // 數(shù)據(jù)庫更新播放列表中的歌曲。&l

57、t;/p><p><b>  });</b></p><p>  return convertView;</p><p><b>  }</b></p><p>  class ViewHolder {</p><p>  TextView music_count;</p&

58、gt;<p>  TextView music_name;</p><p>  TextView music_singer;</p><p>  LinearLayout subLay;</p><p><b>  }</b></p><p><b>  }</b></p>

59、<p>  圖4-4 播放列表的歌曲界面</p><p>  Adapter編寫好之后,使用Adapter代碼如下:</p><p>  View view= inflater.inflate(R.layout.local_music, null);</p><p>  ListView listingView = (ListView) view.fi

60、ndViewById(R.id.local_music_listview);</p><p>  ListingMusicAdapter listingAdapter = new ListingMusicAdapter(this,listingMusics);</p><p>  listingView .setAdapter(listingAdapter); // ListView調(diào)用s

61、etAdapter方法。</p><p>  listingView .setOnItemClickListener(itemPlayListener);</p><p>  播放器很多界面都需要編寫Adapter,原理是一樣的,不同的是getView方法根據(jù)不同布局效果的重寫內(nèi)容。</p><p>  4.2.3 掃描文件的實現(xiàn)</p><p&

62、gt;  項目設(shè)定兩種掃描歌曲文件的方式。一鍵掃描,掃描SDCard中所有歌曲文件;自定義掃描,掃描用戶指定的文件夾中MP3歌曲文件。第一種方式,使用系統(tǒng)對外提供ContentProvider的URI(統(tǒng)一資源標(biāo)識符,標(biāo)記唯一性的),</p><p>  MediaStore.Audio.Media.EXTERNAL_CONTENT_URI。</p><p>  Cursor cursor

63、 = getContentResolver().query(</p><p>  MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,</p><p>  MediaStore.Audio.Media.DEFAULT_SORT_ORDER);</p><p>  獲得Cursor對象,對其進(jìn)行循

64、環(huán)遍歷可以得到所有歌曲,然后進(jìn)行存儲。</p><p>  String musicName = cursor.getString(cursor //獲取歌曲的名字</p><p>  .getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));</p><p>  String album = cursor.getS

65、tring(cursor //獲取歌曲專輯名字</p><p>  .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));</p><p>  String artist = cursor.getString(cursor //獲取歌手名字</p><p>  .getColumnIndexOrThrow(M

66、ediaStore.Audio.Media.ARTIST));</p><p>  String url = cursor.getString(cursor //獲取歌曲所在文件目錄路徑</p><p>  getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));</p><p>  當(dāng)用戶點擊自定義掃描,頁面會切換到

67、另一個Activity,界面如圖4-5所示。</p><p>  這個界面需要編寫Adapter,然后給CheckBox注冊監(jiān)聽器。</p><p>  圖4-5 自定義掃描歌曲的界面</p><p>  用戶選中某些文件夾,然后編寫遞歸方法對文件夾檢測所包含的MP3文件,存儲到一個集合中,再重新對該集合中文件路徑遍歷,與系統(tǒng)提供的歌曲URI遍歷的路徑比較,相等即可

68、獲取歌曲信息,并保存到數(shù)據(jù)庫中。</p><p>  4.2.4 數(shù)據(jù)存取的實現(xiàn)</p><p>  掃描文件,需要保存在數(shù)據(jù)庫中。保存到Sqlite數(shù)據(jù),需要新建一張表。Android系統(tǒng)提供一個SQLiteOpenHelper類,設(shè)計者繼承這個類就可以很方便的建立一張數(shù)據(jù)表,重寫OnCreate方法,執(zhí)行建表的SQL語句(SQL語句的編寫與大部分?jǐn)?shù)據(jù)庫建表的語法是相同的)即可。表建好之

69、后就是設(shè)計者要編寫對表增刪改查四種操作的業(yè)務(wù)邏輯代碼。以下是SQLite操作簡要的代碼:</p><p><b>  第一步:創(chuàng)建表</b></p><p>  public void onCreate(SQLiteDatabase db){</p><p>  //編寫創(chuàng)建表的SQL語句 “create table ”+TABLE_NAME+

70、...</p><p>  //執(zhí)行SQL語句: db.execSQL(sql)</p><p><b>  }</b></p><p>  第二步: 打開數(shù)據(jù)庫,調(diào)用getWritableDatabase()方法</p><p>  private SQLiteDatabase db;</p><p

71、>  public SqlBo(Context context){</p><p>  db = new DBHelper(context).getWritableDatabase();</p><p><b>  }</b></p><p>  第三步:編寫數(shù)據(jù)操作方法:</p><p>  public voi

72、d insert(Music music){ //保存歌曲</p><p>  // insert into編寫插入一條記錄的SQL語句;</p><p>  //執(zhí)行db.execSQL(sql,new Object[]{})</p><p><b>  }</b></p><p>  public Lis

73、t<Music> findAllMusic() { //獲取所有歌曲</p><p>  Cursor cursor = db.rawQuery("select * from " + DBHelper.TABLE_NAME,null);</p><p>  //對cursor對象進(jìn)行循環(huán)遍歷,保存到集合中</p><p><

74、;b>  }</b></p><p>  public Music findMusicById(int id) { //獲取單個Music對象</p><p>  Cursor cursor = db.rawQuery("select * from " + DBHelper.TABLE_NAME</p><p>  + &

75、quot; where _id=?", new String[] { id + "" });</p><p>  //遍歷cursor,創(chuàng)建music對象,然后給music對象屬性賦值</p><p><b> ?。?lt;/b></p><p>  public int updateFavorite(Music m)

76、{ //修改歌曲信息</p><p>  //執(zhí)行 db.update(表名,修改的值,字段名,字段值);語句</p><p><b>  }</b></p><p>  public void deleteAll() { //清空所有歌曲信息</p><p>  db.delete(DBHelper.T

77、ABLE_NAME, null, null);</p><p><b>  }</b></p><p>  4.2.5 手勢滑動的實現(xiàn)</p><p>  Android系統(tǒng)支持手勢功能,播放器添加了對手勢的支持。當(dāng)用戶滑動屏幕,頁面會跳轉(zhuǎn),歌詞會改變進(jìn)度,這些都需要手勢來完成的。手勢的實現(xiàn)思路如下:</p><p> 

78、 implements OnGestureListener,OnTouchListener</p><p>  //實現(xiàn)或注冊上述兩個監(jiān)聽器接口</p><p>  private GestureDetector mGestureDetector; //用于識別手勢的對象</p><p>  //onCreate方法中,給mGestureDetector賦值<

79、/p><p>  mGestureDetector = new GestureDetector(this);</p><p>  public boolean onTouch(View v, MotionEvent event) {</p><p>  return mGestureDetector.onTouchEvent(event);</p><

80、;p><b>  }</b></p><p>  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) { //重寫onFling方法</p><p>  float x1 = e1.getX();</p><p>

81、  float x2 = e2.getX();</p><p>  //檢測兩點間的距離和滑動時的速率velocityX</p><p>  //判斷滑動時的方向(左右)和速率</p><p><b>  }</b></p><p>  4.2.6 歌詞顯示的實現(xiàn)</p><p>  歌詞的實現(xiàn)前

82、提是歌詞文件與歌曲文件名字相同,在同一目錄下,而且歌詞文件格式是lrc。設(shè)計思路是自定義一個LrcView繼承View重寫OnDraw方法,在定義一個Lrc歌詞對象,聲明onDraw方法,讓對象自己進(jìn)行繪制。代碼思路如下:</p><p>  public class LrcView extends View{</p><p>  protected void onDraw(Canvas

83、canvas) {</p><p>  lrc.onDraw(canvas, getWidth(), getHeight());</p><p>  //lrc對象自己繪制,傳入Canvas作為畫家,設(shè)定畫布的寬和高</p><p><b>  }</b></p><p>  public void updateTime

84、(int currentPosition) {</p><p>  lrc.updateTime(currentPosition);//及時更新顯示歌詞播放時間</p><p><b>  }</b></p><p><b>  }</b></p><p>  public class Lrc {&

85、lt;/p><p>  1.判斷有沒有歌詞文件,有就用IO流讀取歌詞文件,解析出時間和內(nèi)容</p><p>  2.把解析出的時間和內(nèi)容封裝成一個對象存放,在把這個對象存放到List集合中。</p><p>  3.根據(jù)播放歌曲進(jìn)度傳入的參數(shù)在Lrc對象中定義的onDraw方法中動態(tài)改變歌詞</p><p><b>  顯示的內(nèi)容和位置

86、</b></p><p><b>  }</b></p><p>  歌詞的顯示難點是怎么確定一句話顯示的位置,也就是第一個字的顯示的x,y坐標(biāo)。已知LrcView的寬width和高h(yuǎn)eight,根據(jù)Paint對象,可以求出一句話所占的面積,即寬textWidth=p.measureText(str)和高textHeight=p.getSize()。<

87、;/p><p>  X = (width-textWidth)/2; 求出x的坐標(biāo)。圖4-6 求出y坐標(biāo)圖例</p><p>  圖4-6 求出y坐標(biāo)</p><p>  手勢滑動改變播放進(jìn)度及歌詞的顯示,是在播放歌曲的Activity中給LrcView設(shè)置OnTouchListener,重寫onTouch方法,判斷是否移動和移動的距離,然后與y坐標(biāo)相加或相減。移動距離

88、的變化值除以所有歌詞包括間距的總距離的比值等于播放的進(jìn)度的變化值除以歌曲總進(jìn)度。從而求出播放進(jìn)度的變化值,然后加上當(dāng)前播放的進(jìn)度,就可以改變歌曲的播放進(jìn)度。</p><p>  4.2.7 播放歌曲的實現(xiàn)</p><p>  播放歌曲用到了Android中的另一個重要控件Service。Service本質(zhì)同Activity是一樣的,但是Service是沒有界面的而Activity有界面,S

89、ervice可以當(dāng)應(yīng)用退出Activity銷毀的時候依然運行在手機(jī)后臺中。以下介紹Service的使用。</p><p>  //創(chuàng)建Service</p><p>  public class MusicService extends Service {</p><p>  public void onCreate() {</p><p>

90、  super.onCreate();</p><p>  player = new MediaPlayer(); //初始化MediaPlayer對象</p><p>  manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//初始化NotificationManager對象 </p>

91、<p><b>  }</b></p><p>  //Service同Activity類似,也是由系統(tǒng)創(chuàng)建對象的,所以需要定義在AndroidMainfest.xml文件聲明定義:</p><p>  <service android:name="com.chxy.service.MusicService"</p>

92、<p>  android:screenOrientation="portrait" /></p><p>  //重寫onBind方法,這是能夠與Activity交互的常用途徑</p><p>  public IBinder onBind(Intent arg0) {</p><p>  return new MyBind

93、er();</p><p><b>  }</b></p><p>  public class MyBinder extends Binder {</p><p>  //Service的啟動只會執(zhí)行一次onCreate方法,當(dāng)與Activity綁定,onBind方法得到調(diào)用,返回MyBinder對象,然后操作MyBinder對象去播放歌曲和

94、顯示通知欄。</p><p><b>  }</b></p><p>  //Service與Activity綁定</p><p>  private MusicService.MyBinder binder;//聲明binder對象</p><p>  //創(chuàng)建一個ServiceConnection對象,當(dāng)綁定和解綁A

95、ctivity時作為參數(shù)傳入</p><p>  private ServiceConnection conn = new ServiceConnection() {</p><p>  public void onServiceDisconnected(ComponentName name) {</p><p><b>  }</b><

96、/p><p>  public void onServiceConnected(ComponentName name, IBinder service) {</p><p>  binder = (MusicService.MyBinder) service; //調(diào)用Service的onBind方法。</p><p>  //需要做一些處理,比如更新SeekBar的進(jìn)

97、度顯示</p><p><b>  }</b></p><p><b>  };</b></p><p><b>  //啟動并綁定服務(wù)</b></p><p>  if (null == binder) {</p><p>  Intent inten

98、t = new Intent(this, MusicService.class);</p><p>  startService(intent); //啟動MusicService服務(wù)</p><p>  bindService(intent, conn, BIND_AUTO_CREATE); </p><p>  //綁定服務(wù),onServiceConnected

99、得到調(diào)用,給binder對象賦值。</p><p><b>  }</b></p><p>  //停止綁定和停止服務(wù)</p><p>  unbindService(conn); //解除綁定</p><p>  Intent intent = new Intent(HomeActivity.this, MusicSe

100、rvice.class);</p><p>  stopService(intent); //停止服務(wù)</p><p>  當(dāng)服務(wù)啟動并綁定好之后,就只需要操縱binder對象,所以在binder類中定義播放和控制的代碼。下面說明歌曲的播放代碼思路:</p><p>  player.reset(); //播放歌曲前先前置</p><p> 

101、 player.setAudioStreamType(AudioManager.STREAM_MUSIC);</p><p>  //聲音大小隨手機(jī)的設(shè)置變化</p><p>  musicUri = Uri.parse(music.getMusic_path());</p><p>  //根據(jù)路徑轉(zhuǎn)換成URI對象</p><p>  pl

102、ayer.setDataSource(MusicService.this, musicUri);</p><p><b>  //添加播放的歌曲</b></p><p>  player.prepare(); //準(zhǔn)備播放</p><p>  player.setOnPreparedListener(preparedListener);//當(dāng)

103、準(zhǔn)備完畢后播放</p><p>  player.setOnCompletionListener(listener); </p><p>  //當(dāng)播放完畢后處理其他邏輯代碼,比如下一首播放</p><p>  OnPreparedListener preparedListener = new OnPreparedListener() {</p>&l

104、t;p>  public void onPrepared(MediaPlayer mp) {</p><p>  mp.start();// 開始播放歌曲</p><p><b>  }</b></p><p><b>  };</b></p><p>  OnCompletionListen

105、er listener = new OnCompletionListener() {</p><p>  public void onCompletion(MediaPlayer mp) {</p><p>  //下一首,還是單曲循環(huán),等等邏輯代碼的處理</p><p><b>  }</b></p><p><

106、b>  };</b></p><p><b>  //播放其他操作</b></p><p>  player.pause(); //暫停播放</p><p>  player.start(); //暫停繼續(xù)播放</p><p>  player.seekTo(progress); //改變播放歌曲的進(jìn)度

107、</p><p>  //關(guān)閉服務(wù),必須釋放MediaPlayer所占的資源</p><p>  if (player.isPlaying()) {</p><p>  player.stop();//停止播放</p><p><b>  }</b></p><p>  player.releas

108、e();//釋放資源</p><p>  進(jìn)度條的同步更新,使用了Handler,每隔1s中調(diào)用一次binder中所定義的獲得SeekBar進(jìn)度的方法。SeekBar進(jìn)度的公式如下:</p><p>  seekProgress = player.getCurrentPosition() * 100 / musicLength;</p><p>  musicLen

109、gth = player.getDuration();</p><p>  然后seekbar.setProgress(seekProgress);就同步更新進(jìn)度條了。</p><p>  SeekBar注冊O(shè)nSeekBarChangeListener監(jiān)聽器,重寫的onStopTrackingTouch方法里,傳入?yún)?shù)seekProgress,執(zhí)行下面語句</p><

110、p>  player.seekTo(seekProgress * musicLength / 100); //通過binder對象調(diào)用</p><p>  當(dāng)拖拽SeekBar就改變播放歌曲的進(jìn)度。</p><p>  當(dāng)歌曲播放完成后,只需要改變索引位置,放入新的Music對象的URI,重復(fù)執(zhí)行播放歌曲的流程。</p><p><b>  播放器運

111、行測試</b></p><p>  為了方便截圖演示,本次測試在480*800分辨率,Android 2.2系統(tǒng)版本的模擬器下進(jìn)行測試,測試效果如下:</p><p>  1.掃描歌曲效果圖:圖5-1為一鍵掃描效果圖,圖5-2為自定義掃描完成后的效果圖,當(dāng)歌曲很多情況下,是需要花費一定時間的,但不會讓手機(jī)卡住。</p><p>  圖5-1 一鍵掃描完成

112、</p><p>  圖5-2 自定義掃描完成</p><p>  掃描完成后,本地歌曲列表顯示界面如圖5-3所示。點擊紅心按鈕,添加或者移除最愛歌曲,點擊加號按鈕,添加歌曲到播放列表中。</p><p>  圖5-3 本地歌曲列表</p><p>  播放歌曲顯示的界面如圖5-4所示,歌詞同步顯示,SeekBar同步更新進(jìn)度,上下拖拽歌詞,

113、同步改變播放進(jìn)度。拖拽SeekBar,改變播放進(jìn)度和歌詞顯示。</p><p>  圖5-4 播放歌曲界面</p><p><b>  參考文獻(xiàn)</b></p><p>  [1] 李剛. 瘋狂Android講義[M]. 北京:電子工業(yè)出版社,2011.</p><p>  [2] 李剛. 瘋狂Java講義[M].北京:

114、電子工業(yè)出版社,2012.</p><p>  [3] 吳亞峰. Android應(yīng)用案例開發(fā)大全[M]. 北京:人民郵電出版社,2011.</p><p>  [4] 苗忠良,宛斌,等. Android多媒體編程從初學(xué)到精通[M].北京:電子工業(yè)出版社,2011.</p><p>  [5] 許正華. 程序員的創(chuàng)新修煉[J]. 程序員, 2012.05(5):82-

115、85.</p><p>  [6] 肖梓航. Android軟件安全開發(fā)實踐[J]. 程序員, 2012-09(9):82-85.</p><p>  [7] 王哲. Android敏捷開發(fā)指南[J]. 程序員, 2012-09(9):86-89.</p><p>  [8] 莊明浩. 移動互聯(lián)網(wǎng)創(chuàng)業(yè)路向何方?[J]. 程序員, 2012-10(10):32-35.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論