距離上個版本也好幾天了,因為有些問題到現在才搞定!1.3版本主要是增加了一個歌曲列表的功能,點擊歌曲列表上的歌曲,再按播放就可以播放音樂了,xml檔案增加了兩個:
songlist.xml:
<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout<br /> xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"><br /> <ListView android:id="@id/android:list"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> android:layout_weight="1"<br /> android:drawSelectorOnTop="false"<br /> /><br /> <TextView android:id="@id/android:empty"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> android:text="@string/list_nosong"<br /> /><br /></LinearLayout><br />
注意:他的組件的id是系統預設的,第一個ListView是顯示列表,第二個TextView是在列表為空白時才顯示
song_item.xml:
<?xml version="1.0" encoding="utf-8"?><br /> <TextView android:id="@+id/text1" xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"/>
這個xml檔案是定義前一個xml檔案中ListView中每個list的顯示方式
main.xml 中增加了一個播放清單按鈕:
<Button android:id="@+id/button_songlist"<br />android:layout_width="wrap_content"<br />android:layout_height="wrap_content"<br />android:text="@string/button_songlist"<br />/>
String.xml:
<string name="button_songlist">播放清單</string><br /> <string name="list_nosong">Sorry!No songs found on SD Card!</string>
新增了一個SongList類用來在SD卡上尋找歌曲並顯示在歌曲列表上
SongList.java:
package com.android.musicPlayer;<br />import java.io.File;<br />import java.io.FilenameFilter;<br />import java.util.ArrayList;<br />import java.util.List;<br />import android.os.Bundle;<br />import android.util.Log;<br />import android.view.View;<br />import android.widget.ArrayAdapter;<br />import android.widget.ListView;<br />import android.app.ListActivity;<br />import android.content.Intent;<br />public class SongList extends ListActivity {<br />private static final String MEDIA_PATH = "/sdcard/";<br />private List<String> songs = new ArrayList<String>();<br />protected void onCreate(Bundle savedInstanceState){<br />super.onCreate(savedInstanceState);<br />setContentView(R.layout.songlist);<br />updateSongList();<br />}</p><p>private class Mp3Filter implements FilenameFilter {<br />@Override<br />public boolean accept(File dir, String name) {<br />// TODO Auto-generated method stub<br />return (name.endsWith(".mp3"));<br />}<br />}<br />//尋找SD卡中所有歌曲<br />public void updateSongList() {<br />File home = new File(MEDIA_PATH);<br />if(home.listFiles(new Mp3Filter()).length>0) {<br />for(File file:home.listFiles(new Mp3Filter())) {<br />songs.add(file.getName());<br />}<br />ArrayAdapter<String> adapter_songs = new ArrayAdapter<String>(this, R.layout.song_item, songs);<br />//綁定到ListActivity上<br />setListAdapter(adapter_songs);<br />}<br />}<br />@Override<br />protected void onListItemClick(ListView l, View v, int position, long id) {<br />// TODO Auto-generated method stub<br />super.onListItemClick(l, v, position, id);<br />//<br />String path = songs.get(position);</p><p>//把儲存了歌曲地址的intent傳遞給MusicPlayer<br />Intent intent_path = new Intent();<br />intent_path.setClass(this, MusicPlayer.class);<br />intent_path.setAction(MusicService.SONG_LIST);<br />Bundle bundle_path = new Bundle();<br />bundle_path.putString("song_path", MEDIA_PATH+path);<br />intent_path.putExtras(bundle_path);<br />startActivity(intent_path);<br />}<br />}<br />
歌曲列表
歌曲是事先儲存進去的,如果不知道怎麼把歌曲儲存到SD上可以看我的另一篇文章http://blog.csdn.net/ldj299/archive/2010/08/18/5822512.aspx
之前兩個類,MusicPlayer類中主要修改如下:
private Button button_songList;//播放清單<br />private String path=null;<br />private Uri uri = null;</p><p> private void findView() {<br /> //....................<br />button_songList = (Button)findViewById(R.id.button_songlist);<br />button_songList.setId(3);<br /> }<br /> private void setListener(){<br /> //..........<br /> button_songList.setOnClickListener(buttonListener);<br /> }<br />private Button.OnClickListener buttonListener = new Button.OnClickListener(){<br />@Override<br />public void onClick(View v) {<br />//按下播放清單這個按鈕不擷取Intent<br />if(v.getId()!=3) {<br />//獲得SongList傳過來的Intent<br />Bundle songList = getIntent().getExtras();<br />path = songList.getString("song_path");<br />uri = Uri.parse(path);<br />}<br />//根據之前為每個Button設定的Id值實現對應的功能<br />switch(v.getId()) {<br />case 0 :<br />if(!(button_start.getText()=="暫停")) {<br /> Intent intent_start = new Intent(MusicService.PLAY_ACTION);<br />intent_start.setClass(MusicPlayer.this, MusicService.class);<br />intent_start.setData(uri);<br />startService(intent_start);<br />}<br />//按鈕顯示文字與播放與暫停功能的互換<br />if(button_start.getText()=="暫停") {<br />button_start.setText("播放");<br />Intent intent_pause = new Intent(MusicService.PAUSE_ACTION);<br />intent_pause.setClass(MusicPlayer.this, MusicService.class);<br />startService(intent_pause);<br />}else {<br />button_start.setText("暫停");<br />}<br />break;<br />case 1 :<br />if(button_start.getText()=="暫停") {<br />button_start.setText("播放");<br />}<br />Intent intent_stop = new Intent(MusicService.STOP_ACTION);<br />intent_stop.setClass(MusicPlayer.this, MusicService.class);<br />startService(intent_stop);<br />break;<br />case 2 :<br />Intent intent_loop= new Intent(MusicService.LOOP_ACTION);<br />intent_loop.setClass(MusicPlayer.this, MusicService.class);<br />startService(intent_loop);</p><p>//按鈕顯示文字與功能的互換<br />if(button_loop.getText()=="取消重複") {<br />button_loop.setText("重複");</p><p>Intent intent_notLoop= new Intent(MusicService.NOTLOOP_ACTION);<br />intent_notLoop.setClass(MusicPlayer.this, MusicService.class);<br />startService(intent_notLoop);<br />Toast.makeText(MusicPlayer.this, "重複已關閉", Toast.LENGTH_SHORT).show();<br />}else {<br />button_loop.setText("取消重複");<br />Toast.makeText(MusicPlayer.this, "重複已開啟", Toast.LENGTH_SHORT).show();<br />}<br />break;<br />case 3:<br />Intent intent_songlist = new Intent();<br />intent_songlist.setClass(MusicPlayer.this, SongList.class);<br />startActivity(intent_songlist);<br />}<br />}<br /> };
MusicService主要修改如下:
public void onCreate() {<br />super.onCreate();<br />init();<br />}<br />public void onStart(Intent intent,int startId) {<br />super.onStart(intent, startId);<br />if(intent != null){<br />String action = intent.getAction();<br />if(action.equals(PLAY_ACTION)) {<br />//利用isCreate變數控制對象在必要時才初始化<br />if(isCreate==false) {<br />initByPath(intent.getData());<br />}<br />//判斷如果有歌曲在播放就停止現正播放的音樂<br />if(player.isPlaying()==true) {<br />stop();<br />initByPath(intent.getData());<br />}<br />play();//播放<br />isCreate = true;<br />}else if(action.equals(PAUSE_ACTION)) {<br />pause();//暫停<br />}else if(action.equals(STOP_ACTION)) {<br />stop();//停止<br />isCreate = false;<br />}else if(action.equals(LOOP_ACTION)) {<br />looping(true);//重複<br />}else if(action.equals(NOTLOOP_ACTION)) {<br />looping(false);//取消重複<br />}<br />}<br />}<br />private void init() {<br />player = new MediaPlayer();//對象初始化避免拋出null 指標異常<br />}<br />private void initByPath(Uri uri) {//對象初始化<br />player = MediaPlayer.create(this,uri);<br />}
建立了一個Activity,在AndroidManifest.xml中加入如下代碼:
<activity android:name=".SongList" android:label="@string/app_list"></activity>
我都只是寫的修改的或增加的以前沒變的就沒寫了,播放的時候有個問題就是一定要先在播放清單中選擇歌曲後才能播放,一開始就按播放會報錯,問題還是有很多的,以後的版本會慢慢改進的,寫這個版本的時候遇到了好多問題,弄了幾天也沒搞定,今天下午把電腦關了,在紙上分析了問題的原因,想了想解決的辦法,弄完之後就去打了打球,回來洗個澡,再去偵錯工具,沒多久就OK了,我覺得有時候遇到錯誤解決不了的話,是需要跳出來不要一直困在裡面,學會分析,調試錯誤本來就是學習編程的一部分,所以我們不要怕錯誤!解決之後又是我們的一次成長!今天就到這吧,大家一起加油!