`
cyw
  • 浏览: 33229 次
  • 来自: 广州
社区版块
存档分类
最新评论

Andoird通信之简单聊天ChatApp

阅读更多

Andoird通信之简单聊天ChatApp

Android通信,大体上的逻辑是跟Java上的通信是差不多的,只是因为Android线程不能直接访问UI界面组件,所以在处理的时候有些麻烦,只要是通过Handle处理。

接下来是一个简单地手机聊天App,主要是手机终端与电脑之间的通信,比如发文字或者是发送图片。

因为涉及到发送不同类型的文件,所以需要制定以下协议:

1、消息类型,使用一个int表示,4个字节:

1、表示文字数据包;

2、表示鱼片数据包。

2、数据包的长度,使用一个int表示,4个字节

3、数据内容,使用字节数组进行传输。

 

关键性代码:

1、服务机与客户机之间的链接:

服务机:

ServerSocket ss = new ServerSocket(port);

Socket socket = ss.accept();

客户机:

//这个地方不能填电脑的本机地址,一定要是局域网或公网的//IP地址,wifi

socket = new Socket("10.96.23.74", 8888);

2、发送文字的代码:

//发送数据类型, 1-文本, 2-图片

dataOutputStream.writeInt(1);

//发送数据长度

dataOutputStream.writeInt(bytes. length);

//发送数据内容

dataOutputStream.write(bytes);

3、发送图片的代码:

//把一个图片文件读取到一个字节数组中

FileInputStream fis = new FileInputStream("images/jobs.png");

int len = fis.available();

byte[] bytes = new byte[len];

fis.read(bytes);

fis.close();

//发送数据类型, 1-文本, 2-图片

dataOutputStream.writeInt(2);

//数据长度

dataOutputStream.writeInt(bytes. length);

//数据内容

dataOutputStream.write(bytes);

//刷新缓存

dataOutputStream.flush();

4、Handle处理UI界面:

在客户机线程里面,handler.sendMessage(msg);

MainActivity里面:

//创建Handler对象

Handler handler = new Handler(

//回调接口,当handler接收到消息时调用该接口的handleMessage方法

new Callback() {

//出理线程发送过来的数据

public boolean handleMessage(Message msg) {

if(msg. what == 1){

//把服务器发送过来的内容显示出来

textMsgLog.append(" 服务器: " + msg. obj .toString() +

"\n");

}

if(msg. what == 2){

//服务器发送过来的图片

Bitmap bitmap = (Bitmap)msg. obj ;

ImageSpan imageSpan = new ImageSpan(MainActivity. this,

bitmap);

//创建一个SpannableString对象,以便插//入用ImageSpan对象封装的图像

SpannableString ss = new SpannableString("img");

// 用imageSpan对象替换img

ss.setSpan(imageSpan, 0, 3,

Spannable. SPAN_EXCLUSIVE_EXCLUSIVE);

//把图片显示在界面上

textMsgLog.append(" 服务器: ");

textMsgLog.append(ss);

textMsgLog.append("\n");

}

return true;

}

});

5、在 Android Manifest.xml文件中添加网络权限:

在 uses-sdk 标签后面添加

<uses-permission android:name="android.permission.INTERNET"/>

 

所以,对于服务机

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

 

public class Server {

public void setUp(int port){

try {

//监听port端口

ServerSocket ss = new ServerSocket(port);

//循环接收客户端的访问

while(true){

Socket socket = ss.accept();

//把客户端的连接放到线程里处理

SocketThread st = new SocketThread(socket);

st.start();

}

} catch (IOException e) {

e.printStackTrace();

}

}

 

public static void main(String[] args) {

//服务器监听8888端口

new Server().setUp(8888);

}

}

 

 

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.Socket;

 

public class SocketThread extends Thread {

private Socket socket;

private DataOutputStream dataOutputStream;

 

public SocketThread(Socket socket) {

this. socket = socket;

}

 

public void run(){

try {

//得到网络连接的输入输出流对象

InputStream inputStream = socket.getInputStream();

//用数据输入流对原输入流进行封装,用于读取不同类型的数据

DataInputStream dis = new DataInputStream(inputStream);

//用数据输出流对原输出流进行封装,用于发送不同类型的数据

dataOutputStream = new DataOutputStream(socket.getOutputStream());

while(true){

//读取一个int,注意:这里是readInt方法

int msgType = dis.readInt();

//文字消息

if(msgType == 1){

//读取数据包长度

int len = dis.readInt();

//读取数据内容

byte[] bytes = new byte[len];

dis.readFully(bytes);

//转成字符串

String content = new String(bytes, "GB2312");

System. out.println(" 客户端说: "+content);

//客户端发送过来的字符串为image的话就发送一张图片过去

if(content.equals("image")){

sendImage();

} else {

//向客户端回应信息

String replyString = " 服务器收到了("+content+")";

bytes = replyString.getBytes("GB2312");

//发送数据类型, 1-文本, 2-图片

dataOutputStream.writeInt(1);

//发送数据长度

dataOutputStream.writeInt(bytes. length);

//发送数据内容

dataOutputStream.write(bytes);

//刷新缓存

dataOutputStream.flush();

}

}

//图片数据包

if(msgType == 2){

//读取数据包长度

int len = dis.readInt();

//读取数据内容

byte[] bytes = new byte[len];

dis.readFully(bytes);

//在这里可以把客户端发送的图片保存到文件,也可以做个界面显示出来,具体代码就不写了

 

 

 

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

 

//向客户端发送一张图片

public void sendImage() throws IOException{

//把一个图片文件读取到一个字节数组中

//src/wo.jpg,以文件夹ChatAppServer为起始目录

FileInputStream fis = new FileInputStream("images/wo.jpg");

int len = fis.available();

byte[] bytes = new byte[len];

fis.read(bytes);

fis.close();

//发送数据类型, 1-文本, 2-图片

dataOutputStream.writeInt(2);

//数据长度

dataOutputStream.writeInt(bytes. length);

//数据内容

dataOutputStream.write(bytes);

//刷新缓存

dataOutputStream.flush();

}

}

 

对于客户机

首先是Android页面:

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:orientation="vertical" >

 

<TextView

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:id="@+id/textMsgLog"

 android:text="" />

 

 <LinearLayout

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:orientation="horizontal">

 

 <EditText

android:id="@+id/editInput"

 android:layout_width="220dp"

 android:layout_height="wrap_content" />

 

 <Button

 android:id="@+id/btnSend"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:onClick="send"

 android:text="发送" />

 

</LinearLayout>

</LinearLayout>

 

主页面:

package com.cyw.chatapp;

 

import android.app.Activity;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.os.Handler;

import android.os.Handler.Callback;

import android.os.Message;

import android.text.Spannable;

import android.text.SpannableString;

import android.text.style.ImageSpan;

import android.view.View;

import android.widget.EditText;

import android.widget.TextView;

import android.widget.Toast;

 

public class MainActivity extends Activity {

private TextView textMsgLog;

private ClientThread clientThread;

 

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout. activity_main);

 

//聊天记录组件

textMsgLog = (TextView)findViewById(R.id. textMsgLog);

//创建Handler对象

Handler handler = new Handler(

//回调接口,当handler接收到消息时调用该接口的handleMessage方法

new Callback() {

//出理线程发送过来的数据

public boolean handleMessage(Message msg) {

if(msg. what == 1){

//把服务器发送过来的内容显示出来

textMsgLog.append(" 服务器: " + msg. obj .toString() +

"\n");

}

if(msg. what == 2){

//服务器发送过来的图片

Bitmap bitmap = (Bitmap)msg. obj ;

ImageSpan imageSpan = new ImageSpan(MainActivity. this,

bitmap);

//创建一个SpannableString对象,以便插入用ImageSpan对象封装的图像

SpannableString ss = new SpannableString("img");

// 用imageSpan对象替换img

ss.setSpan(imageSpan, 0, 3,

Spannable. SPAN_EXCLUSIVE_EXCLUSIVE);

//把图片显示在界面上

textMsgLog.append(" 服务器: ");

textMsgLog.append(ss);

textMsgLog.append("\n");

}

return true;

}

});

 

//通信线程,通过handler对象与UI主现象发送数据

clientThread = new ClientThread(handler);

clientThread.start();

}

 

//向服务器发送文本内容

public void send(View v){

EditText editInput = (EditText)findViewById(R.id. editInput);

String msg = editInput.getText().toString();

boolean result = clientThread.sendText(msg);

if(result){

textMsgLog.append(" 我: "+msg+"\n");

editInput.setText("");

else {

Toast. makeText(this" 发送失败", Toast. LENGTH_LONG).show();

}

}

}

 

客户端处理线程:

package com.cyw.chatapp;

 

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.net.Socket;

import java.net.UnknownHostException;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Handler;

import android.os.Message;

 

public class ClientThread extends Thread {

//与UI主线程通信的中间代理

private Handler handler;

private DataOutputStream dataOutputStream;

private DataInputStream dataInputStream;

private Socket socket;

 

public ClientThread(Handler handler){

thishandler = handler;

}

 

//一定记得要在线程里访问网络

public void run(){

try {

//因为连接网络比较耗时间,会阻塞UI主线程

//所以连接到服务器的操作一定要放在线程的run里面

connect();

while(true){

//读取一个int,注意:这里是readInt方法

int msgType = dataInputStream.readInt();

//文字消息

if(msgType == 1){

//读取数据包长度

int len = dataInputStream.readInt();

//读取数据内容

byte[] bytes = new byte[len];

dataInputStream.readFully(bytes);

//转成字符串

String content = new String(bytes, "GB2312");

Message msg = new Message();

//消息类型

msg. what = 1;

//消息内容

msg. obj = content;

//发送给UI主线程

handler.sendMessage(msg);

}

//图片数据包

if(msgType == 2){

//读取数据包长度

int len = dataInputStream.readInt();

//读取数据内容

byte[] bytes = new byte[len];

dataInputStream.readFully(bytes);

//把字节数组还原成一个图片

Bitmap bitmap = BitmapFactory. decodeByteArray(bytes,

0, len);

Message msg = new Message();

//消息类型

msg. what = 2;

//消息内容

msg. obj = bitmap;

//发送给UI主线程

handler.sendMessage(msg);

}

}

catch (IOException e) {

e.printStackTrace();

finally {

close();

}

}

 

//链接主机

private void connect() throws UnknownHostException, IOException {

//这个地方不能填电脑的本机地址,一定要是局域网或公网的IP地址,wifi

//IPv4 地址: 10.96.23.74  IPv6 地址: 2001:250:4400:d000::3:97b8

socket = new Socket("10.96.23.74", 8888);

//得到输入输出流对象

dataInputStream = new DataInputStream(socket.getInputStream());

dataOutputStream = new DataOutputStream(socket.getOutputStream());

}

 

//关闭网络连接

private void close(){

if(dataInputStream != null){

try {

dataInputStream.close();

catch (IOException e) {

}

}

if(dataOutputStream != null){

try {

dataOutputStream.close();

catch (IOException e) {

}

}

if(socket != null){

try {

socket.close();

catch (IOException e) {

}

}

}

 

//向服务器发送数据

public boolean sendText(String content){

try {

//把字符串转成字节数组

byte[] bytes = content.getBytes("GB2312");

//消息类型

dataOutputStream.writeInt(1);

//数据长度

dataOutputStream.writeInt(bytes. length);

//发送数据

dataOutputStream.write(bytes);

dataOutputStream.flush();

return true;

catch (IOException e) {

e.printStackTrace();

}

return false;

}

}

 

<!--EndFragment-->
0
0
分享到:
评论
2 楼 cyw 2015-03-13  
Long_yuan 写道
用 netty吧

谢了。正好想去研究一下netty,求推荐好的博客
1 楼 Long_yuan 2015-03-13  
用 netty吧

相关推荐

    android bluetooth chat app

    总之,"android bluetooth chat app"的开发涵盖了Android蓝牙API的使用、网络连接的建立与维护、数据传输、用户界面设计和多线程编程等多个Android开发核心技能。在实际开发过程中,还需考虑权限管理、错误处理以及...

    Android socket通信聊天,客户端+服务端

    本文将深入探讨如何在Android中实现基于Socket的客户端和服务端通信,以构建一个简单的聊天应用。 首先,让我们理解Socket的基本概念。Socket是网络通信中的一个编程接口,它允许两台计算机通过网络进行数据交换。...

    android系统的聊天室设计代码

    在Android平台上设计一个聊天室应用是一项复杂而有趣的任务,它涉及到多个技术层面,包括网络通信、数据存储、用户界面设计以及实时消息同步等。在这个"android系统的聊天室设计代码"中,我们可以预见到一系列关键的...

    flutter_chatapp

    【标题】"flutter_chatapp" 是一个基于Flutter框架开发的实时聊天应用程序。它展示了如何使用Flutter构建具有实时通信功能的应用,使用户能够即时发送和接收消息。 【描述】"实时聊天"是指应用能够立即更新并显示新...

    Android二人聊天室

    【Android二人聊天室】是一个基于Android平台开发的简易聊天应用,设计用于两个用户之间通过WiFi共享网络进行实时通信。这个项目的核心目标是实现一个基本的即时通讯功能,让两个设备可以互相发送文本消息,为用户...

    ChatApp:使用Android Studio创建的用于聊天的应用程序

    ChatApp是一款基于Android Studio开发的简单聊天应用,它利用了Firebase这一强大的云平台来实现数据存储和用户身份验证。在这款应用中,用户可以发送文本消息、图片或者其他媒体类型的信息,进行实时交流。以下是...

    Android聊天APP源码.zip

    【Android聊天APP源码】是针对安卓平台开发的一款即时通讯应用的源代码,它提供了基本的聊天功能,可能包括文字、语音、图片等多样化的消息类型。开发者可以通过研究这个源码来学习如何在Android平台上构建类似的...

    ChatApp:是在Android中开发的聊天应用程序,在PHP和Firebase中开发的后端应用程序用于通知

    1. **Android开发**:ChatApp是使用Java编程语言开发的,这是Android平台上最常用的语言之一。开发者需要熟悉Android SDK,以及如何使用Android Studio进行项目构建和调试。应用程序的设计遵循Material Design指南,...

    Android-一个Android聊天应用具备私聊和群聊功能

    综上所述,开发一个具备私聊和群聊功能的Android聊天应用,需要掌握多种技术,包括但不限于用户界面设计、数据库管理、网络通信、实时性处理、安全性策略、多线程编程、国际化、测试和版本控制。每一个环节都是确保...

    XMPPChatDemoForAndroid

    XMPPChatDemoForAndroid是一个基于Android平台的XMPP聊天应用示例,它使用了ASMACK库来实现与OpenFire服务器的交互。这个项目为开发者提供了一个基础的框架,用于理解和构建自己的即时通讯应用。 首先,我们需要...

    Android-基于环信的简单通信的实现

    在Android平台上,构建一个基于环信(Easemob)的简单通信应用是一个常见的任务,尤其对于那些希望创建即时通讯(IM)功能的开发者来说。环信是一个专业的即时通讯云服务提供商,它提供了丰富的API和SDK,使得开发者...

    Chat.zip_android IM_android wechat_im app_like wechat_wechat

    本项目“Chat.zip”正是针对Android平台开发的一款类似微信的即时通讯应用,旨在为用户提供便捷、高效的沟通体验。 一、Android即时通讯基础 Android即时通讯应用的核心是通过网络进行实时的数据传输。这涉及到...

    Chat-Android:Android平台上的聊天软件

    Chat-Android是一款专为Android平台设计的聊天应用,它的核心是使用Java编程语言进行开发。在深入了解这个项目之前,我们先来了解一下Java在Android开发中的重要性以及Android聊天软件的基本架构。 Java是Android...

    chatapp:ionic_angularJS聊天项目

    为了实现聊天应用中的实时通信功能,`chatapp`可能会使用WebSocket或者Firebase。WebSocket提供双向通信,允许服务器主动推送消息到客户端,而Firebase是Google提供的实时云数据库,可以轻松实现数据同步和实时更新...

    Uniapp实现IM聊天,支持厂商通道,可以编译成各种小程序,Android/iOS app

    本文将深入探讨如何使用Uniapp框架来构建一个集成即时通讯(IM)功能的聊天应用程序,同时支持厂商通道,使得该应用能够编译为微信小程序、支付宝小程序、百度智能小程序等多种平台的小程序,以及Android和iOS原生...

    Android局域网群聊app

    在Android平台上开发一款局域网群聊应用,可以利用网络编程技术实现在同一网络环境下的设备间通信。这里,我们主要关注三个核心知识点:局域网通信、多线程以及Android Studio的使用。 1. **局域网通信**:局域网...

    ChatApp:这是一个Android应用程序,用户可以在其中与他人进行通信。 它提供了用户登录和注销功能。 在这里,经过身份验证的用户可以相互发送文本消息,语音消息,图像等。 它使用Firebase实时数据库

    ChatApp是一款基于Android平台的通信应用,其核心功能是让用户能够与他人进行实时交流。这款应用采用Java语言编写,这是Android开发的主流语言之一,具备广泛的应用基础和丰富的社区资源。在ChatApp中,用户可以享受...

    uni-app聊天页面

    【uni-app聊天页面】是一个基于uni-app框架开发的聊天界面模板,它旨在为开发者提供一个类似于微信聊天体验的用户界面,适用于多种平台,包括iOS、Android以及H5等。uni-app是一个多端开发框架,由DCloud(即海螺...

Global site tag (gtag.js) - Google Analytics