您的位置:首页 > 移动开发 > 微信开发

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

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

/article/6123594.html

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

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

package com.fuly.util;

import java.io.IOException;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;

//播放录音的类
public class RecoderPlayer {

private static MediaPlayer mMediaPlayer;
private static boolean isPause = false;//是否为暂停播放

//播放音乐

public void playSound(String filePath) {

if(mMediaPlayer == null){

mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener(new OnErrorListener() {

public boolean onError(MediaPlayer mp, int what, int extra) {

mMediaPlayer.reset();
return false;
}
});
}else{
mMediaPlayer.reset();

}

try {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

//暂停播放
public static void pause(){

if(mMediaPlayer != null && mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
isPause = true;
}

}

//复位播放

public static void reset(){

if(mMediaPlayer != null && isPause){

mMediaPlayer.start();
isPause = false;
}
}

//释放资源
public static void release(){

if(mMediaPlayer != null){
mMediaPlayer.release();
mMediaPlayer = null;
}
}

}


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

package com.fuly.util;

//封装录音信息的类
public class Recoder {

public int mTime;
public String filePath;

public Recoder(int mTime, String filePath) {
super();
this.mTime = mTime;
this.filePath = filePath;
}

public int getmTime() {
return mTime;
}

public void setmTime(int mTime) {
this.mTime = mTime;
}

public String getFilePath() {
return filePath;
}

public void setFilePath(String filePath) {
this.filePath = filePath;
}

}


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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">

<ImageView
android:id="@+id/id_icon"
android:layout_width="65dp"
android:layout_height="65dp"
android:src="@drawable/icon"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_alignParentRight="true"/>

<FrameLayout
android:id= "@+id/id_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/id_icon"
android:background="@drawable/chatto_bg_focused"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp">

<ImageView
android:id="@+id/img_voice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/adj"/>

</FrameLayout>

<TextView
android:id ="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/id_frame"
android:layout_marginRight="3dp"
android:text=""
android:textColor="@color/red"
android:layout_marginTop="20dp"/>

</RelativeLayout>


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

package com.fuly.util;

import java.util.List;

import com.fuly.irecoder.R;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

public class MyAdapter extends ArrayAdapter<Recoder> {

private Context mContext;

private int width;//屏幕宽度

public MyAdapter(Context context, List<Recoder> datas) {
super(context, -1,datas );
mContext = context;

//下面的代码为获得屏幕宽度
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metric = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metric);
width = metric.widthPixels;

}

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder vh = null;

if(convertView == null){

convertView = LayoutInflater.from(mContext).inflate(R.layout.listitem, parent, false);
vh = new ViewHolder();

vh.tv = (TextView) convertView.findViewById(R.id.tv_time);
vh.fl = (FrameLayout) convertView.findViewById(R.id.id_frame);

convertView.setTag(vh);

}else{

vh = (ViewHolder) convertView.getTag();
}

vh.tv.setText(getItem(position).mTime+"\"");//设定显示的时间
//下面三句为设定vh.fl的宽度
LayoutParams lp = vh.fl.getLayoutParams();
int w = width*getItem(position).mTime/35;
lp.width = w>(width*3/4)?(width*3/4):w;

return convertView;
}

class ViewHolder{

private TextView tv;
private FrameLayout fl;
}
}


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

package com.fuly.irecoder;

import java.util.ArrayList;
import java.util.List;

import com.fuly.util.MyAdapter;
import com.fuly.util.Recoder;
import com.fuly.util.RecoderButton;
import com.fuly.util.RecoderButton.RecoderButtonListener;
import com.fuly.util.RecoderPlayer;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {

private ListView mListView ;
private MyAdapter mAdapter;
private List<Recoder> mDatas = new ArrayList<Recoder>();

private RecoderPlayer mPlayer;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mListView = (ListView) findViewById(R.id.rec_listview);
RecoderButton button = (RecoderButton) findViewById(R.id.btn_recoder);

button.setOnRecoderButtonListener(new RecoderButtonListener() {

public void onFinish(int mTime, String filePath) {

Recoder recoder = new Recoder(mTime,filePath);

mDatas.add(recoder);

mAdapter.notifyDataSetChanged();//通知状态发生改变,即有新数据添加进来

//设置ListView为最后一一项
mListView.setSelection(mDatas.size()-1);

}
});

mAdapter = new MyAdapter(this, mDatas);
mListView.setAdapter(mAdapter);

mListView.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {

//播放音频

mPlayer = new RecoderPlayer();

//OnCompletionListener是播放结束的监听器
mPlayer.playSound(mDatas.get(position).filePath);

}
});

}

@Override
protected void onPause() {
RecoderPlayer.pause();
super.onPause();
}

@Override
protected void onRestart() {
RecoderPlayer.reset();
super.onRestart();
}

@Override
protected void onDestroy() {
RecoderPlayer.release();
mDatas.clear();
super.onDestroy();
}

}


至此,我们的整个项目算是完成了。赶快运行一下,看看效果吧。如果对界面不满意,可以自己再调调哦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: