网络对讲机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