Android--MediaPlayer(实现列表选歌,上一首,下一首,清空播放列表,搜索本地音乐文件)

 

下载链接:http://download.csdn.net/detail/zlqqhs/5079025

 

MediaPlayerActivity类:

 

  1. <span style="font-size:14px;">package com.vince.media;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7. import java.util.concurrent.ExecutorService;  
  8. import java.util.concurrent.Executors;  
  9. import android.app.Activity;  
  10. import android.app.ProgressDialog;  
  11. import android.media.MediaPlayer;  
  12. import android.media.MediaPlayer.OnCompletionListener;  
  13. import android.media.MediaPlayer.OnErrorListener;  
  14. import android.os.Bundle;  
  15. import android.os.Environment;  
  16. import android.os.Handler;  
  17. import android.os.Message;  
  18. import android.view.Menu;  
  19. import android.view.MenuItem;  
  20. import android.view.View;  
  21. import android.view.ViewGroup;  
  22. import android.widget.AdapterView;  
  23. import android.widget.AdapterView.OnItemClickListener;  
  24. import android.widget.BaseAdapter;  
  25. import android.widget.ImageButton;  
  26. import android.widget.ListView;  
  27. import android.widget.SeekBar;  
  28. import android.widget.SeekBar.OnSeekBarChangeListener;  
  29. import android.widget.TextView;  
  30. import android.widget.Toast;  
  31.   
  32. public class MediaPlayerActivity extends Activity implements OnCompletionListener,OnErrorListener,OnSeekBarChangeListener,OnItemClickListener,Runnable{  
  33.   
  34.     protected static final int SEARCH_MUSIC_SUCCESS = 0;// 搜索成功标记  
  35.     private SeekBar seekBar;  
  36.     private ListView listView;  
  37.     private ImageButton btnPlay;  
  38.     private TextView tv_currTime,tv_totalTime,tv_showName;  
  39.     private List<String> list;  
  40.     private ProgressDialog pd; // 进度条对话框  
  41.     private MusicListAdapter ma;// 适配器  
  42.     private MediaPlayer mp;  
  43.     private int currIndex = 0;// 表示当前播放的音乐索引  
  44.     private boolean flag = true;//控制进度条线程标记  
  45.   
  46.     // 定义当前播放器的状态״̬  
  47.     private static final int IDLE = 0;  
  48.     private static final int PAUSE = 1;  
  49.     private static final int START = 2;  
  50.     private static final int CURR_TIME_VALUE = 1;  
  51.   
  52.     private int currState = IDLE; // 当前播放器的状态  
  53.     //定义线程池(同时只能有一个线程运行)  
  54.     ExecutorService es = Executors.newSingleThreadExecutor();  
  55.   
  56.     @Override  
  57.     protected void onCreate(Bundle savedInstanceState) {  
  58.         super.onCreate(savedInstanceState);  
  59.         setContentView(R.layout.mediaplayer_layout);  
  60.         list = new ArrayList<String>();  
  61.         mp = new MediaPlayer();  
  62.         mp.setOnCompletionListener(this);  
  63.         mp.setOnErrorListener(this);  
  64.         initView();  
  65.     }  
  66.   
  67.     @Override  
  68.     protected void onDestroy() {  
  69.         if (mp != null) {  
  70.             mp.stop();  
  71.             flagfalse;  
  72.             //释放资源  
  73.             mp.release();  
  74.         }  
  75.         super.onDestroy();  
  76.     }  
  77.   
  78.     /**  
  79.      * 初始化UI组件  
  80.      */  
  81.     private void initView() {  
  82.         btnPlay = (ImageButton) findViewById(R.id.media_play);  
  83.         seekBar = (SeekBar) findViewById(R.id.seekBar1);  
  84.         seekBar.setOnSeekBarChangeListener(this);  
  85.         listView = (ListView) findViewById(R.id.listView1);  
  86.         listView.setOnItemClickListener(this);  
  87.         tv_currTime = (TextView) findViewById(R.id.textView1_curr_time);  
  88.         tv_totalTime = (TextView) findViewById(R.id.textView1_total_time);  
  89.         tv_showName = (TextView) findViewById(R.id.tv_showName);  
  90.     }  
  91.   
  92.     @Override  
  93.     public boolean onCreateOptionsMenu(Menu menu) {  
  94.         //从xml文件中装载菜单  
  95.         getMenuInflater().inflate(R.menu.media_menu, menu);  
  96.         return super.onCreateOptionsMenu(menu);  
  97.     }  
  98.   
  99.     private Handler hander = new Handler() {  
  100.         public void handleMessage(android.os.Message msg) {  
  101.             switch (msg.what) {  
  102.             case SEARCH_MUSIC_SUCCESS:  
  103.                 //搜索音乐文件结束时  
  104.                 ma = new MusicListAdapter();  
  105.                 listView.setAdapter(ma);  
  106.                 pd.dismiss();  
  107.                 break;  
  108.             case CURR_TIME_VALUE:  
  109.                 //设置当前时间  
  110.                 tv_currTime.setText(msg.obj.toString());  
  111.                 break;  
  112.             default:  
  113.                 break;  
  114.             }  
  115.         };  
  116.     };  
  117.   
  118.     @Override  
  119.     public boolean onOptionsItemSelected(MenuItem item) {  
  120.         switch (item.getItemId()) {  
  121.         //搜索本地音乐菜单  
  122.         case R.id.item1_search:  
  123.             list.clear();  
  124.             //是否有外部存储设备  
  125.             if (Environment.getExternalStorageState().equals(  
  126.                     Environment.MEDIA_MOUNTED)) {  
  127.                 pd = ProgressDialog.show(this, "", "正在搜索音乐文件...", true);  
  128.                 new Thread(new Runnable() {  
  129.                     String[] ext = { ".mp3" };  
  130.                     File file = Environment.getExternalStorageDirectory();  
  131.   
  132.                     public void run() {  
  133.                         search(file, ext);  
  134.                         hander.sendEmptyMessage(SEARCH_MUSIC_SUCCESS);  
  135.                     }  
  136.                 }).start();  
  137.   
  138.             } else {  
  139.                 Toast.makeText(this, "请插入外部存储设备..", Toast.LENGTH_LONG).show();  
  140.             }  
  141.   
  142.             break;  
  143.         //清除播放列表菜单  
  144.         case R.id.item2_clear:  
  145.             list.clear();  
  146.             ma.notifyDataSetChanged();  
  147.             break;  
  148.         //退出菜单  
  149.         case R.id.item3_exit:  
  150.             flag = false;  
  151.             this.finish();  
  152.             break;  
  153.         }  
  154.         return super.onOptionsItemSelected(item);  
  155.     }  
  156.   
  157.     // 搜索音乐文件  
  158.     private void search(File file, String[] ext) {  
  159.         if (file != null) {  
  160.             if (file.isDirectory()) {  
  161.                 File[] listFile = file.listFiles();  
  162.                 if (listFile != null) {  
  163.                     for (int i = 0; i < listFile.length; i++) {  
  164.                         search(listFile[i], ext);  
  165.                     }  
  166.                 }  
  167.             } else {  
  168.                 String filename = file.getAbsolutePath();  
  169.                 for (int i = 0; i < ext.length; i++) {  
  170.                     if (filename.endsWith(ext[i])) {  
  171.                         list.add(filename);  
  172.                         break;  
  173.                     }  
  174.                 }  
  175.             }  
  176.         }  
  177.     }  
  178.   
  179.     class MusicListAdapter extends BaseAdapter {  
  180.   
  181.         public int getCount() {  
  182.             return list.size();  
  183.         }  
  184.   
  185.         public Object getItem(int position) {  
  186.             return list.get(position);  
  187.         }  
  188.   
  189.         public long getItemId(int position) {  
  190.             return position;  
  191.         }  
  192.   
  193.         public View getView(int position, View convertView, ViewGroup parent) {  
  194.             if (convertView == null) {  
  195.                 convertView = getLayoutInflater().inflate(R.layout.list_item,  
  196.                         null);  
  197.             }  
  198.             TextView tv_music_name = (TextView) convertView  
  199.                     .findViewById(R.id.textView1_music_name);  
  200.             tv_music_name.setText(list.get(position));  
  201.             return convertView;  
  202.         }  
  203.   
  204.     }  
  205.   
  206.     private void play() {  
  207.         switch (currState) {  
  208.         case IDLE:  
  209.             start();  
  210.             break;  
  211.         case PAUSE:  
  212.             mp.pause();  
  213.             btnPlay.setImageResource(R.drawable.ic_media_play);  
  214.             currState = START;  
  215.             break;  
  216.         case START:  
  217.             mp.start();  
  218.             btnPlay.setImageResource(R.drawable.ic_media_pause);  
  219.             currState = PAUSE;  
  220.         }  
  221.     }  
  222.   
  223.     //上一首  
  224.     private void previous() {  
  225.         if((currIndex-1)>=0){  
  226.             currIndex--;  
  227.             start();  
  228.         }else{  
  229.             Toast.makeText(this, "当前已经是第一首歌曲了", Toast.LENGTH_SHORT).show();  
  230.         }  
  231.     }  
  232.   
  233.     //下一自首  
  234.     private void next() {  
  235.         if(currIndex+1<list.size()){  
  236.             currIndex++;  
  237.             start();  
  238.         }else{  
  239.             Toast.makeText(this, "当前已经是最后一首歌曲了", Toast.LENGTH_SHORT).show();  
  240.         }  
  241.     }  
  242.   
  243.     //开始播放  
  244.     private void start() {  
  245.         if (list.size() > 0 && currIndex < list.size()) {  
  246.             String SongPath = list.get(currIndex);  
  247.             mp.reset();  
  248.             try {  
  249.                 mp.setDataSource(SongPath);  
  250.                 mp.prepare();  
  251.                 mp.start();  
  252.                 initSeekBar();  
  253.                 es.execute(this);  
  254.                 tv_showName.setText(list.get(currIndex));  
  255.                 btnPlay.setImageResource(R.drawable.ic_media_pause);  
  256.                 currState = PAUSE;  
  257.             } catch (IOException e) {  
  258.                 e.printStackTrace();  
  259.             }  
  260.         }else{  
  261.             Toast.makeText(this, "播放列表为空", Toast.LENGTH_SHORT).show();  
  262.         }  
  263.     }  
  264.       
  265.     //播放按钮  
  266.     public void play(View v){  
  267.         play();  
  268.     }  
  269.       
  270.     //上一首按钮  
  271.     public void previous(View v){  
  272.         previous();  
  273.     }  
  274.       
  275.     //下一首按钮  
  276.     public void next(View v){  
  277.         next();  
  278.     }  
  279.   
  280.     //监听器,当当前歌曲播放完时触发,播放下一首  
  281.     public void onCompletion(MediaPlayer mp) {  
  282.         if(list.size()>0){  
  283.             next();  
  284.         }else{  
  285.             Toast.makeText(this, "播放列表为空", Toast.LENGTH_SHORT).show();  
  286.         }  
  287.     }  
  288.   
  289.     //当播放异常时触发  
  290.     public boolean onError(MediaPlayer mp, int what, int extra) {  
  291.         mp.reset();  
  292.         return false;  
  293.     }  
  294.       
  295.     //初始化SeekBar  
  296.     private void initSeekBar(){  
  297.         seekBar.setMax(mp.getDuration());  
  298.         seekBar.setProgress(0);  
  299.         tv_totalTime.setText(toTime(mp.getDuration()));  
  300.     }  
  301.       
  302.     private String toTime(int time){  
  303.         int minute = time / 1000 / 60;  
  304.         int s = time / 1000 % 60;  
  305.         String mm = null;  
  306.         String ss = null;  
  307.         if(minute<10)mm = "0" + minute;  
  308.         else mm = minute + "";  
  309.           
  310.         if(s <10)ss = "0" + s;  
  311.         else ss = "" + s;  
  312.           
  313.         return mm + ":" + ss;  
  314.     }  
  315.   
  316.     public void run() {  
  317.         flag = true;  
  318.         while(flag){  
  319.             if(mp.getCurrentPosition()<seekBar.getMax()){  
  320.                 seekBar.setProgress(mp.getCurrentPosition());  
  321.                 Message msg = hander.obtainMessage(CURR_TIME_VALUE, toTime(mp.getCurrentPosition()));  
  322.                 hander.sendMessage(msg);  
  323.                 try {  
  324.                     Thread.sleep(500);  
  325.                 } catch (InterruptedException e) {  
  326.                     e.printStackTrace();  
  327.                 }  
  328.             }else{  
  329.                 flag = false;  
  330.             }  
  331.         }  
  332.     }  
  333.   
  334.     //SeekBar监听器  
  335.     public void onProgressChanged(SeekBar seekBar, int progress,  
  336.             boolean fromUser) {  
  337.         //是否由用户改变  
  338.         if(fromUser){  
  339.             mp.seekTo(progress);  
  340.         }  
  341.     }  
  342.   
  343.     public void onStartTrackingTouch(SeekBar seekBar) {  
  344.     }  
  345.   
  346.     public void onStopTrackingTouch(SeekBar seekBar) {  
  347.     }  
  348.   
  349.     //ListView监听器  
  350.     public void onItemClick(AdapterView<?> parent, View view, int position,  
  351.             long id) {  
  352.         currIndex = position;  
  353.         start();  
  354.     }  
  355. }  
  356. </span>  


 

mediaplayer_layout.xml布局文件:

 

  1. <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <ListView  
  8.         android:id="@+id/listView1"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="0dp"  
  11.         android:layout_weight="1" >  
  12.     </ListView>  
  13.   
  14.     <TextView  
  15.         android:id="@+id/tv_showName"  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:gravity="center" />  
  19.   
  20.     <LinearLayout  
  21.         android:id="@+id/linearLayout2"  
  22.         android:layout_width="match_parent"  
  23.         android:layout_height="wrap_content"  
  24.         android:gravity="center" >  
  25.   
  26.         <TextView  
  27.             android:id="@+id/textView1_curr_time"  
  28.             android:layout_width="wrap_content"  
  29.             android:layout_height="wrap_content"  
  30.             android:layout_marginRight="5dp"  
  31.             android:text="00:00" />  
  32.   
  33.         <SeekBar  
  34.             android:id="@+id/seekBar1"  
  35.             android:layout_width="fill_parent"  
  36.             android:layout_height="wrap_content"  
  37.             android:layout_weight="1" />  
  38.   
  39.         <TextView  
  40.             android:id="@+id/textView1_total_time"  
  41.             android:layout_width="wrap_content"  
  42.             android:layout_height="wrap_content"  
  43.             android:layout_marginLeft="5dp"  
  44.             android:text="00:00" />  
  45.     </LinearLayout>  
  46.   
  47.     <LinearLayout  
  48.         android:id="@+id/linearLayout1"  
  49.         android:layout_width="match_parent"  
  50.         android:layout_height="wrap_content"  
  51.         android:gravity="center" >  
  52.   
  53.         <ImageButton  
  54.             android:layout_width="wrap_content"  
  55.             android:layout_height="wrap_content"  
  56.             android:onClick="previous"  
  57.             android:src="@drawable/ic_media_previous" />  
  58.   
  59.         <ImageButton  
  60.             android:id="@+id/media_play"  
  61.             android:layout_width="wrap_content"  
  62.             android:layout_height="wrap_content"  
  63.             android:onClick="play"  
  64.             android:src="@drawable/ic_media_play" />  
  65.   
  66.         <ImageButton  
  67.             android:layout_width="wrap_content"  
  68.             android:layout_height="wrap_content"  
  69.             android:onClick="next"  
  70.             android:src="@drawable/ic_media_next" />  
  71.     </LinearLayout>  
  72.   
  73. </LinearLayout></span>  


 

media_menu.xml文件:

 

  1. <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.   
  4.     <item  
  5.         android:id="@+id/item1_search"  
  6.         android:icon="@drawable/ic_menu_search"  
  7.         android:orderInCategory="100"  
  8.         android:title="@string/search">  
  9.     </item>  
  10.     <item  
  11.         android:id="@+id/item2_clear"  
  12.         android:icon="@drawable/ic_menu_delete"  
  13.         android:orderInCategory="200"  
  14.         android:title="@string/clear_music_list">  
  15.     </item>  
  16.     <item  
  17.         android:id="@+id/item3_exit"  
  18.         android:icon="@drawable/ic_menu_close_clear_cancel"  
  19.         android:orderInCategory="300"  
  20.         android:title="@string/exit">  
  21.     </item>  
  22.   
  23. </menu></span>  


 

strings.xml文件:

 

    1. <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  
    2. <resources>  
    3.   
    4.     <string name="hello">Hello World, MediaActivity!</string>  
    5.     <string name="app_name">Media</string>  
    6.     <string name="search">搜索本地音乐</string>  
    7.     <string name="clear_music_list">清除播放列表</string>  
    8.     <string name="exit">退出</string>  
    9.   
    10. </resources></span>  
posted @ 2013-02-22 21:59  爱生活,爱编程  阅读(13915)  评论(1编辑  收藏  举报