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

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

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

因为这个版本只是功能实现的测试版,所以界面做的很丑,请大家见谅,主要看功能哦!!

主要功能:

连接服务器,并开启一个监听来信的线程,如果有来信,开启接收文件线程;

按钮控制发送语音线程;

使用第三方类实现原生未压缩的录音格式 .wav;

使用android 系统自带的mediaPlayer 实现声音播放功能;

第一步: 连接服务器

btnConnect.setOnClickListener(newButton.OnClickListener()

               {

                       @Override

                       publicvoid onClick(View arg0) {

                               //TODO Auto-generated method stub

                               //IP=etIp.getContext().toString();

                               IP= etIp.getText().toString();

                               try{

                                      Port= Integer.parseInt(etPort.getText().toString());

                               }catch(Exceptione)

                               {

                                      Log.i(Tag,"IP"+IP+"port"+Port);

                                      Toast.makeText(MainActivity.this,"请输入正确的端口号!!",Toast.LENGTH_LONG).show();

                                      return;

                               }

                               try{

                                      client= new Socket(IP, Port);           //连接服务器

                               }catch (UnknownHostException e) {

                                      //TODO Auto-generated catch block

                                      e.printStackTrace();

                                      Toast.makeText(MainActivity.this,"UnknownHostException", Toast.LENGTH_LONG).show();

                                      return;

                               }catch (IOException e) {

                                      //TODO Auto-generated catch block

                                      e.printStackTrace();

                                      Toast.makeText(MainActivity.this,"IOException!",Toast.LENGTH_LONG).show();

                                      return;

                               }

                              

                               PrintWriterout;

                               try{

                                      out= new PrintWriter(client.getOutputStream(), true);

                                      out.println("Android");                 //向服务器发送客户端名称

                               }catch (IOException e) {

                                      //TODO Auto-generated catch block

                                      e.printStackTrace();

                               }

                               tvState.setText("连接服务器成功!!!");

                               SocketListensListen = new SocketListen(client,mHandler);   //开启监听接收线程

                               sListen.SetControlBar(tvRecvCount);

                               sListen.start();

                       }

       });

第二步:监听接收线程

    

package er.fly;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

import er.fly.nettandclient.MyHandler;

import android.util.Log;
import android.widget.TextView;

public class SocketListen extends Thread{

	 private Socket client; 
	 //private String savepath="/sdcard/MyVoice/";
	 MyHandler mHandler;
	 MyHandler SLHandler;
	 TextView tvR;
	 public SocketListen(Socket s,MyHandler h)
	 {
		 this.client=s;
		 mHandler = h;
	 }
	 public void SetControlBar(TextView tv)
	 {
		 tvR = tv;
	 }
	 public void run() 
	 {  
		 int len;
	        if (client == null)  
	            return;  
	        while(true)                   //循环监听来信
	        {
	        	BufferedReader in;// = new BufferedReader(new InputStreamReader(System.in));
				// 接收来自 server 的响应数据
							try {
								in = new BufferedReader(new InputStreamReader(client
										.getInputStream()));
								try
								{
										String strlen= in.readLine();   //读取网络流,文件长度
										//System.out.println("File Size :"+strlen);
										Log.i("SocketListen", strlen);
										len = Integer.parseInt(strlen);
										//开启接收文件线程
                                                                                DownloadFile downFile = new DownloadFile(client,len);
                                                                                downFile.SetHanglers(mHandler, SLHandler);
										downFile.SetControlBar(tvR);
										downFile.start();
										//this.suspend();
										while(true)    //判断文件是否接收完成//等待  
										{
											if(!downFile.isAlive())
											break;
										}
								}catch(IOException e)
								{
									Log.i("SocketListen", "no recv");
								}
								
								
								
								
							} catch (IOException e) {
								// TODO Auto-generated catch block
								
								//e.printStackTrace();
							}	 
	        }
	 
	 }
}

接收文件线程类:

package er.fly;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;

import er.fly.nettandclient.MyHandler;

import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
//import er.fly.nettandclient;
public class DownloadFile extends Thread{

	private Socket client;
    File file=null;  
    String sendinfo=null; 
    int fileLen;
    String tag = "DownloadFile"; 
    MyHandler mHandler;                            //用于子线程和主线程通信,更新声音列表
    MyHandler SLHandler;
    TextView tvRecvCount;
    String recvVoiceSavePath;
    public DownloadFile(Socket s,int l)
	{
		 this.client = s;
		 fileLen=l;
	}
    public void SetHanglers(MyHandler m,MyHandler sl)
    {
    	mHandler = m;
    	SLHandler = sl;
    }
    public void SetControlBar(TextView tv)
	 {
		 tvRecvCount = tv;
	 }
    // 创建目录(不存在则创建)  
    public File CreateDir(String dir) {  
        File file = new File(dir);  
        if (!file.exists()) {  
            file.mkdirs();  
        }  
        return file;  
    }  
    public void run()
    {
    	Looper curLooper = Looper.myLooper();
    	Looper mainLooper = Looper.getMainLooper();
    	String msg=null;
    	boolean flag = false;
    	if(client == null)
    	{
    		return ;
    	}
    	try
    	{
    		
			InputStream inputStream = client.getInputStream();
			
			byte[] buffer = new byte[1024];
	    	int readCount = 0;
	    	int count=0;
	    	CreateDir("sdcard/MyRecvVoice/");
	    	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);
	    	BufferedOutputStream fo = new BufferedOutputStream(new FileOutputStream(new File("sdcard/MyRecvVoice/"+strTime+".wav")));
	    	//循环接收文件
	    	while (true) 
	    	{ 
	    		readCount = inputStream.read(buffer);
	    		count = count+readCount;
	    		fo.write(buffer, 0,readCount);
	    		//System.out.println("recv len " + String.valueOf(count)+"readCount "+String.valueOf(readCount));
	    		Log.i(tag, "recv len"+ String.valueOf(count)+"readCount "+String.valueOf(readCount));
	    		if(count>=fileLen)  //判断接收结束
		    		break;
	    	}
	    	
	    	flag = true;
	    	recvVoiceSavePath="sdcard/MyRecvVoice/"+strTime+".wav";
	    	Log.i(tag,"接收成功!!");  
	    	fo.flush();
	    	fo.close();
	    	//inputStream.close();//   一定不能关闭输入输出流,因为关闭它们的同时也会关闭socket    //这个很重要
	    	//outputStream.close();
    	}
    	catch(IOException e)
    	{
    		e.printStackTrace();
    	}
    	
    	mHandler = new MyHandler(mainLooper);
    	mHandler.SetHandlerArgs(tvRecvCount);
    	if(flag)
    		msg="DownloadFile:"+recvVoiceSavePath+"#"+"接收成功!!"; 
    	else
    		msg="DownloadFile:"+"$"+"接收失败!!";
    	mHandler .removeMessages(0);
        Message m = mHandler .obtainMessage(1, 1, 1, msg);//向主线程发信,通知接收结束
        mHandler .sendMessage(m); 
    }
}


发送文件线程类:

package er.fly;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;

import android.util.Log;

public class UpFile extends Thread{

	private Socket client;
    File file=null;  
    String Tag ="UpFile";
    
    public UpFile(Socket client) {  
        this.client = client;  
    }
    public void SetFile(File file){
    	
    	this.file = file;  
    }
    public void run(){
    	if(client == null)
    	{
    		return ;
    	}
    	if(client.isOutputShutdown())
    	{
    		
    		try {
				client.setKeepAlive(true);
			} catch (SocketException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Log.i(Tag, "client setKeepAlive worry");
			}
    	}
    	FileInputStream reader = null;
    	FileInputStream readLen = null;
 
        byte[] buf = null;
    	
        try{
        	InputStream inPut = client.getInputStream();
        	OutputStream outPut = client.getOutputStream();
        	readLen = new FileInputStream(file);
        	ByteArrayOutputStream ow = new ByteArrayOutputStream();
        	int count =0;
        	int buffersize= 256;
        	int fileLen=0;
        	buf = new byte[buffersize];
        	while ((count = readLen.read(buf)) > 0)              //读取文件字节长度
        	{
        		fileLen = fileLen + count;
        	}
        	String strLen =String.valueOf(fileLen);
        	strLen = strLen+"\n";
        	Log.i(Tag, strLen);
        	byte[] buffLen = strLen.getBytes();
        	byte[] buffL = new byte[50];
        	for(int i=0;i<50;i++)                         //把文件字节长度添加到一个长度为50字节数组中   //因为服务也是一次接收50个字节
        	{
        		if(i<buffLen.length)
        		{
        			buffL[i]=buffLen[i];
        		}
        		else
        		{
        			buffL[i]= 0;
        		}
        	}
        	outPut.write(buffL);              //发送文件长度字节数组
        	outPut.flush();                   // 把网络流发送出去,否则服务器接收不到
        	count =0;
                //读取文件字节,并循环发送
        	reader = new FileInputStream(file);
        	while ((count = reader.read(buf)) > 0) 
        	{
        		ow.write(buf, 0, count);
        		Log.i(Tag, "reading file");
        	}  
        	Log.i(Tag, "开始发送!!");
        	outPut.write(ow.toByteArray());
        	outPut.flush();

        	
        	Log.i(Tag, "文件发送完成!!!");
        //    client.shutdownOutput();             //一定不能加这句话,否则socket关闭发送流,以后就不能在此发送,这也是问什么用文件字节长度来判断接收结束原因
        
        }
        catch(Exception e)
        {
        	System.out.println("socket执行异常:" + e.toString()); 
        }finally {
        	try {  
                // 结束对象  
                buf = null;  
               // out.close();        //out一定不能关闭,因为同事也会关闭socket
             //   out.close();
              //  in.close();  
                reader.close();  
               // client.close();  
            } catch (Exception e) {  
  
            }  
        }
    }
}


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


原文地址:https://www.cnblogs.com/javawebsoa/p/3050611.html