网络对讲机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 blocke.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
更多相关文章
- Android Studio添加so文件并打包到APK的lib文件夹中
- android studio打包 so文件
- 【翻译】Android多线程下安全访问数据库
- android 6.0后usb otg设备不显示在文件管理器中
- 将Activity打包成jar文件
- Android子线程真的不能更新UI么