模仿微信语音聊天功能(4) 音频播放实现以及项目结束

 

      在上一篇中,我们实现了核心的录音功能。当然,此时你是没有感觉的,因为我们还没法把它播放出来,所以你还不知道到底有没有录音实现。没读过上一篇的朋友,请点击一下链接:

 http://www.cnblogs.com/fuly550871915/p/4836204.html

 

 

        在这一篇中,我们将实现把录音显示在我们早就设计好的ListView里面,并且点击时,会播放录音。实现过程相对来说比较复杂一些。但是只要有耐心,就能做的好。好了,废话不多说,我们直接看代码。

         首先,我们来实现播放器,代码如下:

 

 1 package com.fuly.util;
 2 
 3 import java.io.IOException;
 4 
 5 import android.media.AudioManager;
 6 import android.media.MediaPlayer;
 7 import android.media.MediaPlayer.OnErrorListener;
 8 
 9 
10 //播放录音的类
11 public class RecoderPlayer {
12     
13     
14     private static MediaPlayer mMediaPlayer;
15     private static boolean isPause = false;//是否为暂停播放
16     
17 
18     //播放音乐
19     
20     public void playSound(String filePath) {
21         
22         if(mMediaPlayer == null){
23             
24             mMediaPlayer = new MediaPlayer();
25             mMediaPlayer.setOnErrorListener(new OnErrorListener() {
26                 
27                 public boolean onError(MediaPlayer mp, int what, int extra) {
28                     
29                     mMediaPlayer.reset();
30                     return false;
31                 }
32             });
33         }else{
34             mMediaPlayer.reset();
35             
36         }
37         
38         
39         
40         try {
41             mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
42             mMediaPlayer.setDataSource(filePath);
43             mMediaPlayer.prepare();
44             mMediaPlayer.start();
45         } catch (IllegalArgumentException e) {
46             e.printStackTrace();
47         } catch (SecurityException e) {
48             e.printStackTrace();
49         } catch (IllegalStateException e) {
50             e.printStackTrace();
51         } catch (IOException e) {
52             e.printStackTrace();
53         }
54         
55     }
56     
57     
58     //暂停播放
59     public static void pause(){
60 
61         if(mMediaPlayer != null && mMediaPlayer.isPlaying()){
62             mMediaPlayer.pause();
63             isPause = true;
64         }
65         
66     }
67     
68     //复位播放
69     
70     public static void reset(){
71         
72         if(mMediaPlayer != null && isPause){
73             
74             mMediaPlayer.start();
75             isPause = false;
76         }
77     }
78     
79     //释放资源
80     public static void release(){
81         
82         if(mMediaPlayer != null){
83             mMediaPlayer.release();
84             mMediaPlayer = null;
85         }
86     }
87 
88 }

      

       接下来就要考虑将播放器集成到ListView中了。首先我们需要一个封装音频信息的类,包括录音的时长和录音存放的绝对路径。代码如下:

 

 1 package com.fuly.util;
 2 
 3 //封装录音信息的类
 4 public class Recoder {
 5     
 6     public int mTime;
 7     public String filePath;
 8     
 9     
10     public Recoder(int mTime, String filePath) {
11         super();
12         this.mTime = mTime;
13         this.filePath = filePath;
14     }
15 
16 
17     public int getmTime() {
18         return mTime;
19     }
20 
21 
22     public void setmTime(int mTime) {
23         this.mTime = mTime;
24     }
25 
26 
27     public String getFilePath() {
28         return filePath;
29     }
30 
31 
32     public void setFilePath(String filePath) {
33         this.filePath = filePath;
34     }
35     
36     
37     
38     
39 
40 }

 

 

       然后为ListView的子项编写布局:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:background="@color/white">
 6     
 7     <ImageView 
 8         android:id="@+id/id_icon"
 9         android:layout_width="65dp"
10         android:layout_height="65dp"
11         android:src="@drawable/icon"
12         android:layout_marginRight="5dp"
13         android:layout_marginTop="5dp"
14         android:layout_alignParentRight="true"/>
15     
16     <FrameLayout 
17        android:id= "@+id/id_frame"
18        android:layout_width="wrap_content"
19        android:layout_height="wrap_content"
20        android:layout_toLeftOf="@id/id_icon"
21        android:background="@drawable/chatto_bg_focused"
22        android:layout_marginRight="5dp"
23        android:layout_marginTop="5dp">
24         
25         <ImageView 
26             android:id="@+id/img_voice"
27             android:layout_width="match_parent"
28             android:layout_height="match_parent"
29             android:background="@drawable/adj"/>
30         
31     </FrameLayout>
32     
33     <TextView 
34         android:id ="@+id/tv_time"
35         android:layout_width="wrap_content"
36         android:layout_height="wrap_content"
37         android:layout_toLeftOf="@id/id_frame"
38         android:layout_marginRight="3dp"
39         android:text=""
40         android:textColor="@color/red"
41         android:layout_marginTop="20dp"/>
42     
43   
44    
45 
46 </RelativeLayout>

 

      然后ListView需要一个适配器,我们建立出来,如下:

 1 package com.fuly.util;
 2 
 3 import java.util.List;
 4 
 5 import com.fuly.irecoder.R;
 6 
 7 import android.content.Context;
 8 import android.util.DisplayMetrics;
 9 import android.view.LayoutInflater;
10 import android.view.View;
11 import android.view.ViewGroup;
12 import android.view.ViewGroup.LayoutParams;
13 import android.view.WindowManager;
14 import android.widget.ArrayAdapter;
15 import android.widget.FrameLayout;
16 import android.widget.ImageView;
17 import android.widget.TextView;
18 
19 public class MyAdapter extends ArrayAdapter<Recoder> {
20 
21     private Context mContext;
22     
23     private int width;//屏幕宽度
24     
25     public MyAdapter(Context context, List<Recoder> datas) {
26         super(context, -1,datas );
27         mContext = context;
28         
29         //下面的代码为获得屏幕宽度
30         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
31         DisplayMetrics metric = new DisplayMetrics();  
32         wm.getDefaultDisplay().getMetrics(metric);  
33          width = metric.widthPixels; 
34         
35     }
36     
37 
38     public View getView(int position, View convertView, ViewGroup parent) {
39         
40         ViewHolder vh = null;
41         
42         if(convertView == null){
43             
44             convertView = LayoutInflater.from(mContext).inflate(R.layout.listitem, parent, false);
45             vh = new ViewHolder();
46             
47             vh.tv = (TextView) convertView.findViewById(R.id.tv_time);
48             vh.fl = (FrameLayout) convertView.findViewById(R.id.id_frame);
49             
50             convertView.setTag(vh);
51             
52         }else{
53             
54             vh = (ViewHolder) convertView.getTag();
55         }
56         
57         
58         vh.tv.setText(getItem(position).mTime+"\"");//设定显示的时间
59         //下面三句为设定vh.fl的宽度
60         LayoutParams lp = vh.fl.getLayoutParams();
61         int w = width*getItem(position).mTime/35;
62         lp.width = w>(width*3/4)?(width*3/4):w;
63         
64         
65         return convertView;
66     }
67     
68     class ViewHolder{
69         
70         private TextView tv;
71         private FrameLayout fl;
72     }
73 }

 

        最后再MainActivity里,我们集成播放器,设置ListView。代码如下:

 

  1 package com.fuly.irecoder;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 import com.fuly.util.MyAdapter;
  7 import com.fuly.util.Recoder;
  8 import com.fuly.util.RecoderButton;
  9 import com.fuly.util.RecoderButton.RecoderButtonListener;
 10 import com.fuly.util.RecoderPlayer;
 11 
 12 import android.media.MediaPlayer;
 13 import android.os.Bundle;
 14 import android.app.Activity;
 15 import android.view.Menu;
 16 import android.view.View;
 17 import android.widget.AdapterView;
 18 import android.widget.AdapterView.OnItemClickListener;
 19 import android.widget.ArrayAdapter;
 20 import android.widget.ListView;
 21 
 22 public class MainActivity extends Activity {
 23     
 24     
 25     private ListView mListView ;
 26     private MyAdapter mAdapter; 
 27     private List<Recoder> mDatas = new ArrayList<Recoder>();
 28     
 29     private RecoderPlayer mPlayer;
 30 
 31   
 32     protected void onCreate(Bundle savedInstanceState) {
 33         super.onCreate(savedInstanceState);
 34         setContentView(R.layout.activity_main);
 35         
 36         mListView = (ListView) findViewById(R.id.rec_listview);
 37         RecoderButton button = (RecoderButton) findViewById(R.id.btn_recoder);
 38         
 39         button.setOnRecoderButtonListener(new RecoderButtonListener() {
 40             
 41     
 42             public void onFinish(int mTime, String filePath) {
 43                 
 44                 Recoder recoder = new Recoder(mTime,filePath);
 45                 
 46                 mDatas.add(recoder);
 47                 
 48                 mAdapter.notifyDataSetChanged();//通知状态发生改变,即有新数据添加进来
 49                 
 50                 //设置ListView为最后一一项
 51                 mListView.setSelection(mDatas.size()-1);
 52     
 53                 
 54             }
 55         });
 56         
 57         mAdapter = new MyAdapter(this, mDatas);
 58         mListView.setAdapter(mAdapter);
 59         
 60         
 61         mListView.setOnItemClickListener(new OnItemClickListener() {
 62 
 63             public void onItemClick(AdapterView<?> parent, View view,
 64                     int position, long id) {
 65                
 66                 
 67                 //播放音频
 68                 
 69                 mPlayer = new RecoderPlayer();
 70                 
 71                 //OnCompletionListener是播放结束的监听器
 72                 mPlayer.playSound(mDatas.get(position).filePath);
 73                 
 74                 
 75                 
 76             }
 77         });
 78         
 79     }
 80     
 81     
 82     @Override
 83     protected void onPause() {
 84         RecoderPlayer.pause();
 85         super.onPause();
 86     }
 87      
 88     @Override
 89     protected void onRestart() {
 90         RecoderPlayer.reset();
 91         super.onRestart();
 92     }
 93     
 94     @Override
 95     protected void onDestroy() {
 96         RecoderPlayer.release();
 97         mDatas.clear();
 98         super.onDestroy();
 99     }
100 
101   
102 }

 

      至此,我们的整个项目算是完成了。赶快运行一下,看看效果吧。如果对界面不满意,可以自己再调调哦。

 

模仿微信语音聊天功能(4) 音频播放实现以及项目结束

上一篇:模仿微信语音聊天功能(2)对话框的实现


下一篇:模仿微信语音聊天功能(3) 核心部分,录音功能的实现