网络对讲机C#服务器 Android客户端(三) android客户端代码分析 附加

完整的工程下载地址(源码):http://download.csdn.net/detail/zhujinghao09/5313666 

录音功能的实现,开始的时候使用android系统自带录音类,但他的编码方式,pc的windowsmediaPlayer 不识别无法播放,所以从网上找一个无压缩的录音类,录音文件格式和windows 一样.

这个录音类宅这里就不贴出来了,有兴趣可以eoe论坛上找一找,也可以下载我的工程源码,里面有

在这简单的使用其实现无压缩录音文件生成:

 

/**
	 * 录制wav格式文件
	 * @param path : 文件路径
	 */
	public static File recordChat(ExtAudioRecorder extAudioRecorder,String savePath,String fileName) {
		File dir = new File(savePath);
		//如果该目录没有存在,则新建目录
		if(dir.list() == null){
			dir.mkdirs();
		}
		//获取录音文件
		File file=new File(savePath+fileName);
		//设置输出文件
		extAudioRecorder.setOutputFile(savePath+fileName);
		extAudioRecorder.prepare();
		//开始录音
		extAudioRecorder.start();
		return file;
	}


	/**
	 * 停止录音
	 * @param mediaRecorder 待停止的录音机
	 * @return 返回
	 */
	public static void stopRecord(final ExtAudioRecorder extAudioRecorder){
		extAudioRecorder.stop();
		extAudioRecorder.release();
	}

//录音按钮

btnRecod.setOnClickListener(new Button.OnClickListener()
		{
			
			@Override
			public void onClick(View arg0) {
				int h = new Date().getHours();
				int m = new Date().getMinutes();
				int s = new Date().getSeconds();
				String strTime = String.valueOf(h)+"-"+String.valueOf(m)+"-"+String.valueOf(s);//获得系统时间命名文件
				String savePath="sdcard/MyVoice/";
				String fileName="ExtAudio"+strTime+".wav";
				// TODO Auto-generated method stub
				extAudioRecorder = ExtAudioRecorder.getInstanse(false); //未压缩的录音(WAV)
				recordChat(extAudioRecorder,savePath,fileName);
				//mRecorder.onStart("er"+strTime);
			  //  lastRecordPath="sdcard/MyVoice/"+"er"+strTime+".amr";
				lastRecordPath=savePath+fileName;           //全局变量
			}
			
		});


停止录音按钮

 

 

btnStop.setOnClickListener(new Button.OnClickListener()
		{

		
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				//mRecorder.onStop();
				stopRecord(extAudioRecorder);
				vPathArrayList.add(lastRecordPath);
				UpdateVoiceListView(vPathArrayList);             //把录音文件路径添加到声音列表
			 
			}
			
		});

播放功能是采用android 系统自带的mediaPlayer

 

播放类:

 

package er.fly;


import java.io.IOException;

import android.media.MediaPlayer;


public class MyMediaPlay {

	MediaPlayer mediaPlayer ;
	public void onPlay(String namePath)
	{
		mediaPlayer = new MediaPlayer();
		if(mediaPlayer.isPlaying())
		{
			mediaPlayer.reset();
		}
		try {
			mediaPlayer.setDataSource(namePath);
			
			mediaPlayer.prepare();
			mediaPlayer.start();
			mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
			{

				@Override
				public void onCompletion(MediaPlayer arg0) {
					// TODO Auto-generated method stub
					mediaPlayer.release();
				}
				
			});
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
	
	
	public void onStop()
	{
		mediaPlayer.stop();
		mediaPlayer.release();
		mediaPlayer=null;
	}
}


播放和发送的文件路径都是从声音列表中读取的

 

 

btnPlay.setOnClickListener(new Button.OnClickListener()
		{

			@Override
			public void onClick(View arg0) {
				
				Log.i(Tag, "Play   "+playSendPath);
				if(playSendPath!=null)
				{
					mPlay.onPlay(playSendPath);
					tvRecvCount.setText("");
				}
				else
					Toast.makeText(MainActivity.this, "请选择要播放的声音!!", Toast.LENGTH_LONG).show();
				playSendPath=null;
			}
			
		});
		btnSend.setOnClickListener(new Button.OnClickListener()
		{

			String Path=null;
			File file;// = new File("sdcard/MyRecvVoice/androidrecv.mp3");
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				if(playSendPath!=null)
				{
					file=new File(playSendPath);
				}
				else
				{
					Toast.makeText(MainActivity.this, "请选择要发送的声音!!", Toast.LENGTH_LONG).show();
					return;
				}
				playSendPath=null;
				UpFile upFile = new UpFile(client);
				upFile.SetFile(file);
				upFile.start();
			}
			
		});


其中

playSendPath 是全局变量通过选择列表控件中元组来百变它的值
public void UpdateVoiceListView(ArrayList<String> al)
    {
    	String[]str =new String[al.size()];
    	for(int i=0;i<al.size();i++)
    	{
    		str[i]=al.get(i);
    	}
    	ArrayAdapter<String> aad= new ArrayAdapter<String>(this, android.R.layout.simple_list_item_checked, str);
    	setListAdapter(aad);
    }
    public void onListItemClick(ListView parent, View v, 
    	    int position, long id) {
    	        CheckedTextView item = (CheckedTextView) v;
    	        String path=vPathArrayList.get(position);
    	        Log.i(Tag, path);
    	        playSendPath=path;
    	    }


 


最后  就是主线程处理来自子线程的消息类:  主要功能是更新主界面控件状态

 

 

package er.fly.nettandclient;

import java.util.ArrayList;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;

public class MyHandler extends Handler {
	TextView tvRecvCount;
	String Tag ="MyHandler";
	//ArrayList<String> voiceAList;
	public MyHandler(Looper looper){
        super (looper);
	}
	 public void SetHandlerArgs(TextView tv)
	 {
		 tvRecvCount = tv;
	 }
	
 @Override
 	public void handleMessage(Message msg) { // 处理消息
	
	 		MainActivity ma = new MainActivity();
	 		String path;
	 		String Dflag="DownloadFile:";
	 		String strMsg=msg.obj.toString();
	 		Log.i(Tag, strMsg);
	 		if(strMsg.indexOf(Dflag)==0)
	 		{
	 			int index1 = strMsg.indexOf("#");
	 			int index2 = strMsg.indexOf("$");
	 			if(index1>0)
	 			{
		 			path = strMsg.substring(Dflag.length(),index1);
		 			Log.i(Tag, path);
		 			MainActivity.vPathArrayList.add(path);
		 			Log.i(Tag, strMsg.substring(index1+1));
		 			tvRecvCount.setText(strMsg.substring(index1+1));
	 			}
	 			if(index2>0)
	 			{
	 				Log.i(Tag, strMsg.substring(index2+1));
		 			tvRecvCount.setText(strMsg.substring(index1+1));
	 			}
	 			
	 		}
 	}        
}
到此,整个项目的基本功能已经可以实现了,有兴趣的朋友可以参照一下。

 

完整的工程下载地址(源码):http://download.csdn.net/detail/zhujinghao09/5313666


posted @ 2013-04-29 13:18  javawebsoa  Views(251)  Comments(0Edit  收藏  举报