Android编程实战——仿微信群聊-3——客户端实现
来源:互联网 发布:多点网络超市 编辑:程序博客网 时间:2024/06/10 01:21
Android编程实战——仿微信群聊-3——客户端实现
项目源代码移步github
客户端类有:Client,ClientMsgThread,MyMessage。
Client用来发送消息,ClientMsgThread是一个不断等待接收消息的线程。
Client类:
public class Client { private Socket client; private ObjectOutputStream oos = null; private ObjectInputStream ois = null; private LinkedBlockingDeque<MyMessage> msgQueue = null; private ClientMsgThread clientMsgThread = null; private final int PORT = 4243; private final String SERVICE_ADDRESS = "192.168.191.1"; public Client() { msgQueue = new LinkedBlockingDeque<>(100); } /** * 连接服务器 */ public void connect() { if (client == null ) { try { System.out.println("请求连接服务器..."); client = new Socket(SERVICE_ADDRESS, PORT); System.out.println("连接服务器成功"); oos = new ObjectOutputStream(client.getOutputStream()); ois = new ObjectInputStream(client.getInputStream()); clientMsgThread = new ClientMsgThread(ois); clientMsgThread.start(); } catch (IOException e) { e.printStackTrace(); } } } /** * 断开连接 */ public void disconnect() { if (client != null) { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 发送请求连接的消息 * @param name 登录姓名 * @return */ public boolean login(String name) { connect(); boolean b =false; try { MyMessage myMessage = new MyMessage(MyMessage.MSG_LOGIN, name); oos.writeObject(myMessage); } catch (IOException e) { e.printStackTrace(); } return b; } /** * 发送语音的消息 * @param filePath * @param time */ public void sendAudioFile(String filePath, float time) { connect(); int length = 0; double sumL = 0; byte[] sendBytes; try { File file = new File(filePath); long l = file.length(); //读取文件数据 FileInputStream fis = new FileInputStream(file); sendBytes = new byte[1024]; System.out.println("开始发送文件"); //发送语音文件的标志信息,表示客户端接下来发送的是语音文件 MyMessage startMessage = new MyMessage(MyMessage.MSG_AUDIO_MARK, "start"); startMessage.setTip(String.valueOf(time)); oos.writeObject(startMessage); oos.flush(); //发送文件 while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0) { MyMessage myMessage = new MyMessage(MyMessage.MSG_AUDIO, sendBytes.clone()); System.out.println("发送长度 " + length); myMessage.setTip(String.valueOf(length)); oos.writeObject(myMessage); oos.flush(); } //文件发送完毕,发送结束标志信息 MyMessage stopMessage = new MyMessage(MyMessage.MSG_AUDIO_MARK, "end"); oos.writeObject(stopMessage); oos.flush(); System.out.println("文件发送完毕"); } catch (IOException e) { e.printStackTrace(); } } /** * 发送文本信息 * @param text 文本内容 */ public void sendText(String text) { connect(); MyMessage myMessage = new MyMessage(MyMessage.MSG_TEXT, text); try { System.out.println("发送文本信息: " + text); oos.writeObject(myMessage); } catch (IOException e) { e.printStackTrace(); } } public boolean isClosed(){ return client.isClosed(); }}
ClientMsgClient类:
public class ClientMsgThread extends Thread { private ObjectInputStream ois = null; public ClientMsgThread(ObjectInputStream ois) { this.ois = ois; } @Override public void run() { System.out.println("接收数据线程启动,等待接收"); while (true) { try { MyMessage myMessage = (MyMessage)ois.readObject(); System.out.println("接收到服务器传来数据,数据类型:" + myMessage.getMsgType()); int msgType = myMessage.getMsgType(); String content = myMessage.getMsgContent(); String sendName = myMessage.getSendName(); if (msgType == MyMessage.MSG_LOGIN) { Message message = new Message(); message.what = 3; Bundle bundle = new Bundle(); bundle.putString("text",content); message.setData(bundle); AudioActivity.handler.sendMessage(message); } else if (msgType == MyMessage.MSG_TEXT) { Message message = new Message(); message.what = 1; Bundle bundle = new Bundle(); bundle.putString("name",sendName); bundle.putString("text",content); message.setData(bundle); AudioActivity.handler.sendMessage(message); } else if (msgType == MyMessage.MSG_AUDIO_MARK && content.equals("start")) { receiveAudio(sendName, Float.valueOf(myMessage.getTip())); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } private void receiveAudio(String username, float time) { FileOutputStream fos = null; String dirPath = AudioFile.RECEIVE_AUDIO_DIR_PATH; //创建文件夹 File dir = new File(dirPath); if (!dir.exists()) { dir.mkdirs(); } try { String userName = username; System.out.println(userName + " " + time); String filePath = dirPath + "/" + Time.getTime() + userName + ".amr"; fos = new FileOutputStream(new File(filePath)); byte[] inputByte; System.out.println("开始接受文件"); while (true) { MyMessage myMessage = (MyMessage) ois.readObject(); System.out.println(myMessage.getMsgType()); if (myMessage.getMsgType() == MyMessage.MSG_AUDIO_MARK && myMessage.getMsgContent().equals("end")) { break; } int length = Integer.valueOf(myMessage.getTip()); inputByte = myMessage.getMsgContentBinary().clone(); System.out.println("接收长度 " + length); fos.write(inputByte, 0, length); fos.flush(); } System.out.println("完成接收"); System.out.println("文件保存路径:" + filePath); //显示语音 Message message = new Message(); message.what = 2; Bundle bundle = new Bundle(); bundle.putString("name",userName); bundle.putString("filePath",filePath); bundle.putFloat("time", time); System.out.println(filePath); message.setData(bundle); AudioActivity.handler.sendMessage(message); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
MyMessage就是和之前相同的类。
public class MyMessage implements Serializable{ private static final long serialVersionUID = 1L; public static final int MSG_AUDIO = 1; //消息类型,语音消息 public static final int MSG_LOGIN = 2; //消息类型,登录消息 public static final int MSG_TEXT = 3; //消息类型,文本消息 public static final int MSG_AUDIO_MARK= 4;// 消息类型,语音消息的标识 private String tip = ""; //额外附带的消息,这里也可以把所有消息放在一起然后通过分隔符区分 private int msgType = -1; //消息类型 private String sendName = ""; //发送者 private String msgContent = ""; //消息内容String private byte[] msgContentBinary; //消息内容,用来传输文件 // Getter Setter public String getTip() { return tip; } public void setTip(String tip) { this.tip = tip; } public void setMsgType(int msgType) { this.msgType = msgType; } public void setMsgContent(String msgContent) { this.msgContent = msgContent; } public byte[] getMsgContentBinary() { return msgContentBinary; } public void setMsgContentBinary(byte[] msgContentBinary) { this.msgContentBinary = msgContentBinary; } public void setSendName(String sendName) { this.sendName = sendName; } public int getMsgType() { return msgType; } public String getSendName() { return sendName; } public String getMsgContent() { return msgContent; } /** * 构造方法 * @param msgType 消息类型 * @param msgContent 消息内容String */ public MyMessage(int msgType, String msgContent) { this.msgType = msgType; this.msgContent = msgContent; } public MyMessage() { } /** * 构造方法 * @param msgType 消息类型 * @param msgContentBinary 消息内容,文件数据 */ public MyMessage(int msgType, byte[] msgContentBinary) { this.msgType = msgType; this.msgContentBinary = msgContentBinary; }}
在传输语音文件中需要注意的一点是,用数组传输二进制数据的时候需要说明数据长度。接收的时候才能正确接收。这里我是把数据长度记录在MyMessage中传输过去。
0 0
- Android编程实战——仿微信群聊-3——客户端实现
- Android编程实战——仿微信群聊-1——服务器端实现
- Android网络编程之——Android登录系统模块的实现(客户端+服务器端Servlet+MySQL)
- Android实战—闹钟的简单实现
- Android网络编程之——Android下菜单系统模块的实现(Android客户端+服务器端Servlet+Mysql)
- Android编程实战——仿微信群聊-5——Android端UI-多种显示的ListView
- 【开源项目】编程博客Android客户端——CodeBlog
- android开发笔记之网络编程—简易新闻客户端
- Scala编程实战—字符串
- Scala编程实战—数值
- 3、CRM2011编程实战——选项集(下拉框)联动效果的实现
- 毕业论文—android客户端
- Android编程实战——仿微信群聊-2——对象的网络传输
- Android编程实战——仿微信群聊-4——Media语音
- Android实战——Zxing实现二维码扫描
- Android实战——Zxing实现二维码扫描
- Android实战——Zxing实现二维码扫描
- Android实战—答题系统的简单实现
- Gitlab上如何给指定人员在指定项目里设置指定权限,给项目设置保护
- ajax file upload 修改
- 算法之路
- Android数据存储五种方式总结
- EditPlus批量修改——正则表达式
- Android编程实战——仿微信群聊-3——客户端实现
- 省市县三级联动
- android ui的几个概念:px,dip(dp),sp,dpi,分辨率等
- 封装生成唯一性ID的算法工具类
- 异步性能:了解 Async 和 Await 的成本
- gdb调试命令的使用及总结
- matlab 求解线性规划问题
- Android6.0 运行时权限简单理解 -- Android学习之路
- 99%的人都理解错了HTTP中GET与POST的区别