zoukankan      html  css  js  c++  java
  • 模仿微信语音聊天功能(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 }

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

  • 相关阅读:
    一文带你看清HTTP所有概念
    程序员不得不了解的硬核知识大全
    看完这篇HTTP,跟面试官扯皮就没问题了
    ReentrantLock 源码分析从入门到入土
    计算机网络的核心概念
    Kafka 的这些原理你知道吗
    2019 我是怎么熬过来的?
    不懂什么是锁?看看这篇你就明白了
    机器学习——方差、协方差与皮尔逊值
    最小生成树的本质是什么?Prim算法道破天机
  • 原文地址:https://www.cnblogs.com/fuly550871915/p/4836230.html
Copyright © 2011-2022 走看看