通过Xsocket实现的Android微信,并不是特别完善,可以在上面进行修改,界面仿照微信进行开发的,Xstream实现XML的传输,可以改成JSON,包括系统的登录,添加好友,聊天,朋友圈啊等功能。使用Activity、intent、SharedPreferences、ContentProvider,BroadcastReceiver、Application、dialog等.
系统从总体上划分可以分为服务器端和客户端。
服务器端主要任务是信息的中转站,通过java和mysql实现,包括信息的接受和发送,数据的存储和转发。客户端包含用户的登陆,注册,聊天,朋友圈等功能,使用android和sqlite实现,主要是实现局域网内的用户的即时通信功能。
系统设计
服务器端示例
定义一个handler类,implements相关接口
1、IDataHandler
2、IConnectHandler,
3、IdleTimeoutHandler
4、IConnectionTimeoutHandler.
当连接成功并收取到数据后,这个handler就会调用。当连接成功并受到数据后,这个handler将会被调用,实现以上接口的函数。
有两种方法启动服务,分别是run()和start().
如果关闭服务器,通过使用server的close()方法.
功能模块的实现
左边是第一次启动应用程序后,介绍本款软件的内容,如果版本更新也会出现此效果。
右边是注册和登陆界面,实现了用户的注册和登陆功能。
注册的会把用户信息存储在第一次启动建立的sqlite本地的数据库,然后把注册信息发送到服务器。服务器也会创建用户,当登陆的时候,使用xStream格式进行发送,把object对象转化为XML数据类型,服务器根据内容匹配确定是否可以登陆。
进入之后会进入类似微信
的界面,下面菜单中分别有微信,通讯录,发现,我。
首先介绍我,可以录入自己的信息,包括右边昵称、手机号、QQ号,性别、个人签名,同时可以进行修改。
刚开始进去没有联系人,需要添加好友才可以进行聊天,需要点击通讯录右上角的添加好友,如果好友存在,提示好友存在,就会有还有提示请求已经发出请求,请等候,对方可以收到好友请求,双方在申请者列表中都有对方的姓名,如果对方同意添加你为好友,在通讯录中就会产出现双发的姓名。
可以试想双方的通信,如果再启动客户端也可以进行三方通信,可以使用表情的添加,以及记录的删除。
这个是朋友圈,你可以给你的朋友发送信息,同时可以赞,也可以发表自己的评论,别人可以看到你发的评论。
服务器端主要源码:
package com.zkq.server;
import java.io.IOException;
import java.net.Socket;
import java.nio.BufferUnderflowException;
import java.nio.channels.ClosedChannelException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.xsocket.MaxReadSizeExceededException;
import org.xsocket.connection.IConnectHandler;
import org.xsocket.connection.IDataHandler;
import org.xsocket.connection.IDisconnectHandler;
import org.xsocket.connection.INonBlockingConnection;
import com.thoughtworks.xstream.XStream;
import com.zkq.dao.impl.PeronDaoImpl;
import com.zkq.model.ChatMsgEntity;
import com.zkq.model.MsgType;
import com.zkq.model.Person;
import com.zkq.model.User;
import com.zkq.server.XsocketServer.XServerTask;
public class EchoHandler implements IDataHandler, IConnectHandler,
IDisconnectHandler {
private static BManager bMan = new BManager();
public static Map<INonBlockingConnection, String> clientList = new HashMap<INonBlockingConnection, String>();
private XStream xStream=new XStream();
@Override
public boolean onDisconnect(INonBlockingConnection nbc) throws IOException {
// TODO 自动生成的方法存根
System.out.println("ondisconnect"+nbc.getRemoteAddress()+":"+nbc.getRemotePort());
// bMan.remove(nbc);
// if (clientList.containsKey(nbc)) {
// clientList
// }
return true;
}
@Override
public boolean onConnect(INonBlockingConnection nbc) throws IOException,
BufferUnderflowException, MaxReadSizeExceededException {
// TODO 自动生成的方法存根
System.out.println("onconnect"+nbc.getRemoteAddress()+":"+nbc.getRemotePort());
return true;
}
@Override
public boolean onData(INonBlockingConnection connection) throws IOException,
BufferUnderflowException, ClosedChannelException,
MaxReadSizeExceededException {
// TODO 自动生成的方法存根
System.out.println("----");
boolean searchflag=true; //是否查到好友标志
String serverdata=connection.readStringByDelimiter("\r\n");
ChatMsgEntity chatMsg=(ChatMsgEntity) xStream.fromXML(serverdata);
String name=chatMsg.getName();
String toname=chatMsg.getSendToUser();
int type=chatMsg.getMsgType();
String text=chatMsg.getText();
System.out.println("type+--------"+type);
switch (type) {
case MsgType.LOGIN:
System.out.println("当前的状态为" + type);
// String userlogindata=connection.readStringByDelimiter("\r\n");
// User user=(User) xStream.fromXML(userlogindata);
// PeronDaoImpl dao=new PeronDaoImpl();
// dao.register(user);
connection.write(serverdata + "\r\n");
bMan.add(connection);
clientList.put(connection, name);
funList(clientList);
break;
case MsgType.SEND:
System.out.println("当前的状态为" + type);
//bMan.sendToAll(data+"\r\n");
INonBlockingConnection bc;
Set set=clientList.keySet();
Iterator it=set.iterator();
while (it.hasNext()) {
Object ok=it.next();
Object ov=clientList.get(ok);
if (ov.equals(toname)) {
bc=(INonBlockingConnection) ok;
chatMsg.setSendToUser(toname);
String senddata=xStream.toXML(chatMsg);
bMan.sendToOne(bc, senddata+"\r\n");
System.out.println(ov+"给"+toname+"发送了"+text);
}else
{
System.out.println("不给发送的用户"+ov);
}
}
System.out.println("单点聊天");
break;
case MsgType.SEND_ALL:
System.out.println("当前的状态"+type);
bMan.sendToAll(serverdata+"\r\n");
// connection.write(serverdata+"\r\n");
connection.flush();
System.out.println("---发送完成---");
break;
case MsgType.LOGOUT:
break;
case MsgType.SEARCH:
System.out.println("当前状态为search");
Set shset=clientList.keySet();
Iterator searchit=shset.iterator();
while (searchit.hasNext()) {
Object ok=searchit.next();
Object ov=clientList.get(ok);
if (ov.equals(toname)) {
System.out.println("找到person");
bc=(INonBlockingConnection) ok;
chatMsg.setComing(true);
String receiveddata=xStream.toXML(chatMsg);
bMan.sendToOne(bc, receiveddata+"\r\n");
chatMsg.setComing(false);
String senddata=xStream.toXML(chatMsg);
connection.write(senddata+"\r\n");
connection.flush();
searchflag=false;
System.out.println(senddata);
}
}
if (searchflag)
{
System.out.println("找不到person");
chatMsg.setComing(false);
chatMsg.setSendToUser("");
String senddata=xStream.toXML(chatMsg);
connection.write(senddata+"\r\n");
connection.flush();
System.out.println(senddata);
}
case MsgType.AGREEFRIEND:
System.out.println("当前的状态为接受目标");
Set agreeset=clientList.keySet();
Iterator agreeit=agreeset.iterator();
while (agreeit.hasNext()) {
Object ok=agreeit.next();
Object ov=clientList.get(ok);
if (ov.equals(toname)) {
bc=(INonBlockingConnection) ok;
bc.write(serverdata+"\r\n");
bc.flush();
System.out.println("agree发送给"+toname);
}
}
break;
default:
break;
}
return true;
}
void funList(Map clientList)
{
String strList="";
Set set=clientList.keySet();
Iterator it=set.iterator();
while (it.hasNext()) {
strList+="--";
strList+=clientList.get(it.next());
}
System.out.println(strList);
//bMan.sendToAll("11"+strList);
}
}
客户端MainActivity源码
package com.zkq.activity;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Vector;
import org.xsocket.connection.IBlockingConnection;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.thoughtworks.xstream.XStream;
import com.zkq.helper.MySqlHelper;
import com.zkq.model.ChatMsgEntity;
import com.zkq.model.Person;
import com.zkq.model.User;
import com.zkq.util.DateFormat;
import com.zkq.util.MsgType;
import com.zkq.util.MyApp;
public class MainActivity extends Activity {
private MySqlHelper mySqlHelper;
private SQLiteDatabase db;
private Button btn_login;
private Button btn_logout;
private Button btn_register;
private EditText name_edit;
private EditText password_edit;
private XStream xStream=new XStream();
private final int PORT=5555;
private IBlockingConnection bc;
private MyApp myApp;
private Vector<UserThread> us=new Vector<UserThread>();
private static final String TAG = MainActivity.class.getName();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySqlHelper = new MySqlHelper(MainActivity.this, "weixin_inf.db", null,
1);
db = mySqlHelper.getWritableDatabase();
btn_login = (Button) findViewById(R.id.login);
btn_logout = (Button) findViewById(R.id.logout);
btn_register = (Button) findViewById(R.id.register);
name_edit = (EditText) findViewById(R.id.username_edittext);
password_edit = (EditText) findViewById(R.id.password_edittext);
myApp=(MyApp) getApplication();
bc=myApp.getBc();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("action.friendcircletext");
registerReceiver(friendcircleBroadcastReceiver, intentFilter);
btn_login.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
login();
}
});
btn_logout.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MainActivity.this, MenuActivity.class);
startActivity(intent);
}
});
btn_register.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
register_person();
}
});
UserThread t1=new UserThread(bc);
new Thread(t1).start();
us.add(t1);
}
private BroadcastReceiver friendcircleBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("action.friendcircletext"))
{
System.out.println("----------成功获取朋友圈的内容");
String name=intent.getStringExtra("name");
String text=intent.getStringExtra("text");
String datestr=intent.getStringExtra("date");
System.out.println("name===="+name);
System.out.println("text____"+text);
System.out.println("date___"+datestr);
ContentValues values=new ContentValues();
values.put("name", name);
values.put("text", text);
values.put("date", datestr);
db.insert("friendcircle", null, values);
System.out.println("----------成功获取朋友圈的内容");
System.out.println("name===="+name);
System.out.println("text____"+text);
}
}
};
Handler handler=new Handler()
{
@Override
public void handleMessage(android.os.Message msg) {
};
};
private void login() {
String username = name_edit.getText().toString();
String password = password_edit.getText().toString();
Cursor cursor = db.rawQuery("select * from person where name ='"
+ username + "'", null);
cursor.moveToNext();
int count = cursor.getCount();
if (count == 1) {
Cursor cursor_login = db.rawQuery(
"select name,password from person where name='" + username
+ "'", null);
cursor_login.moveToNext();
if (username.equals(cursor_login.getString(0))&&password.equals(cursor_login.getString(1))) {
login(username, password);
// Intent intent = new Intent();
// intent.putExtra("name", cursor_login.getString(0));
// intent.setClass(MainActivity.this, MenuActivity.class);
// startActivity(intent);
// login(username, password);
}else {
Toast.makeText(MainActivity.this, "账号或者密码输入错误,请重试", Toast.LENGTH_LONG).show();
name_edit.setText("");
password_edit.setText("");
}
}
}
private void register_person() {
Builder builder = new Builder(MainActivity.this);
LayoutInflater mInflater = LayoutInflater.from(MainActivity.this);
View view = mInflater.inflate(R.layout.register, null);
final Button btn_confirm = (Button) view.findViewById(R.id.confirm);
final Button btn_cancel = (Button) view.findViewById(R.id.cancel);
final EditText username_edit = (EditText) view
.findViewById(R.id.register_user_edit);
final EditText password_edit = (EditText) view
.findViewById(R.id.register_password_edit);
final EditText repassword_edit = (EditText) view
.findViewById(R.id.register_repassword_edit);
final AlertDialog dialog = builder.setTitle("注册").setView(view)
.create();
dialog.show();
btn_confirm.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
String username = username_edit.getText().toString();
String password = password_edit.getText().toString();
String repassword = repassword_edit.getText().toString();
// TODO Auto-generated method stub
if (password.equals(repassword)) {
Cursor cursor = db.rawQuery(
"select * from person where name='" + username
+ "'", null);
Log.i(TAG, "创建成功");
//cursor.moveToNext();
int count = cursor.getCount();
Log.i(TAG, count + "当前的数值");
if (count == 0) {
ContentValues contentValues = new ContentValues();
contentValues.put("name", username);
contentValues.put("password", password);
db.insert("person", null, contentValues);
Toast.makeText(MainActivity.this, "注册成功",
Toast.LENGTH_LONG).show();
Cursor c=db.rawQuery(
"select * from person where name='" + username
+ "'", null);
dialog.dismiss();
cursor.close();
}
} else {
Toast.makeText(MainActivity.this, "两次输入的密码不相同",
Toast.LENGTH_LONG).show();
}
}
});
}
public void login(final String name,final String password)
{
Thread t1=new Thread(new Runnable() {
public void run() {
// TODO 自动生成的方法存根
try {
myApp.setName(name);
ChatMsgEntity loginMsg=new ChatMsgEntity();
loginMsg.setName(name);
Date date=new Date();
String datestr=DateFormat.dateFormat(date);
loginMsg.setDate(datestr);
String logindata=xStream.toXML(loginMsg);
loginMsg.setMsgType(MsgType.LOGIN);
bc.write(logindata+"\r\n");
System.out.println("ddd");
bc.flush();
// User user=new User();
// user.setName(name);
// user.setPassword(password);
// String userlogindata=xStream.toXML(user);
// bc.write(userlogindata+"\r\n");
//new Thread(new UserThread(bc,name)).start();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
});
t1.start();
}
class UserThread implements Runnable
{
IBlockingConnection bc;
private Boolean flag=true;
public UserThread(IBlockingConnection bc) {
// TODO 自动生成的构造函数存根
this.bc=bc;
}
public void run() {
// TODO 自动生成的方法存根
while (flag) {
try {
System.out.println("获取数据");
String data=bc.readStringByDelimiter("\r\n");
ChatMsgEntity msg=(ChatMsgEntity) xStream.fromXML(data);
int type=msg.getMsgType();
String text = msg.getText();
String date = msg.getDate();
//String datestr = DateFormat.dateFormat(date);
String name=msg.getName();
String toUser=msg.getSendToUser();
boolean isComing=msg.isComing();
System.out.println("当前获取到type-----"+type);
System.out.println("从服务器获取的类型"+type);
switch (type) {
case MsgType.LOGIN:
System.out.println("当前为登陆状态");
//flag=false;
Intent intent=new Intent();
intent.putExtra("name",name);
intent.setClass(MainActivity.this, MenuActivity.class);
startActivity(intent);
break;
case MsgType.SEND:
ChatMsgEntity chatMsgEntity = new ChatMsgEntity();
chatMsgEntity.setText(text);
chatMsgEntity.setDate(date);
chatMsgEntity.setName(name);
System.out.println("添加数据");
Intent intentsenddata = new Intent();
intentsenddata.setAction("action.adddata");
intentsenddata.putExtra("name", name);
intentsenddata.putExtra("date", date);
intentsenddata.putExtra("text", text);
sendBroadcast(intentsenddata);
// Message sendmsg = new Message();
// sendmsg.what = 0;
// clientHandler.sendMessage(sendmsg);
break;
case MsgType.SEARCH:
if (isComing) {
System.out.println("0000");
System.out.println(name+"发来邀请请求");
Intent receiveFriendApplyintent = new Intent();
receiveFriendApplyintent.putExtra("name", name);
receiveFriendApplyintent.setAction("action.receiveFriendApply");
sendBroadcast(receiveFriendApplyintent);
}else {
if (toUser.equals("")) {
System.out.println("0000");
System.out.println("不存在");
Intent noThisFriendintent = new Intent();
noThisFriendintent.setAction("action.noThisFriend");
sendBroadcast(noThisFriendintent);
}else
{
System.out.println("0000");
System.out.println("存在");
Intent haveFriend = new Intent();
haveFriend.putExtra("toUser", toUser);
haveFriend.setAction("action.haveFriend");
sendBroadcast(haveFriend);
}
}
break;
case MsgType.AGREEFRIEND:
Intent agreefriend = new Intent();
agreefriend.setAction("action.agreefriend");
agreefriend.putExtra("name", name);
sendBroadcast(agreefriend);
break;
case MsgType.SEND_ALL:
System.out.println("222222222222222");
System.out.println("广播开始了");
Intent fiendcircleiIntent=new Intent();
fiendcircleiIntent.putExtra("name", name);
fiendcircleiIntent.putExtra("text", text);
fiendcircleiIntent.putExtra("date", date);
fiendcircleiIntent.setAction("action.friendcircletext");
sendBroadcast(fiendcircleiIntent);
System.out.println("广播完成");
break;
default:
break;
}
} catch (UnsupportedEncodingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
源码下载地址:
http://download.csdn.net/detail/kai46385076/8205531