码迷,mamicode.com
首页 > 移动开发 > 详细

使用xsocket框架实现的Android即时通讯软件

时间:2014-11-27 20:28:41      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:android   即时通讯   application   xsocket   xstream   


	通过Xsocket实现的Android微信,并不是特别完善,可以在上面进行修改,界面仿照微信进行开发的,Xstream实现XML的传输,可以改成JSON,包括系统的登录,添加好友,聊天,朋友圈啊等功能。使用Activity、intent、SharedPreferences、ContentProvider,BroadcastReceiver、Application、dialog等.

系统从总体上划分可以分为服务器端和客户端。

服务器端主要任务是信息的中转站,通过java和mysql实现,包括信息的接受和发送,数据的存储和转发。

      客户端包含用户的登陆,注册,聊天,朋友圈等功能,使用android和sqlite实现,主要是实现局域网内的用户的即时通信功能。

系统设计

bubuko.com,布布扣



服务器端示例 
定义一个handler类,implements相关接口
1、IDataHandler
2、IConnectHandler,
3、IdleTimeoutHandler
4、IConnectionTimeoutHandler.
当连接成功并收取到数据后,这个handler就会调用。当连接成功并受到数据后,这个handler将会被调用,实现以上接口的函数。
有两种方法启动服务,分别是run()和start().
如果关闭服务器,通过使用server的close()方法.


功能模块的实现

左边是第一次启动应用程序后,介绍本款软件的内容,如果版本更新也会出现此效果。
       右边是注册和登陆界面,实现了用户的注册和登陆功能。
      注册的会把用户信息存储在第一次启动建立的sqlite本地的数据库,然后把注册信息发送到服务器。服务器也会创建用户,当登陆的时候,使用xStream格式进行发送,把object对象转化为XML数据类型,服务器根据内容匹配确定是否可以登陆。

bubuko.com,布布扣bubuko.com,布布扣

进入之后会进入类似微信
的界面,下面菜单中分别有微信,通讯录,发现,我。
首先介绍我,可以录入自己的信息,包括右边昵称、手机号、QQ号,性别、个人签名,同时可以进行修改。

bubuko.com,布布扣bubuko.com,布布扣


        刚开始进去没有联系人,需要添加好友才可以进行聊天,需要点击通讯录右上角的添加好友,如果好友存在,提示好友存在,就会有还有提示请求已经发出请求,请等候,对方可以收到好友请求,双方在申请者列表中都有对方的姓名,如果对方同意添加你为好友,在通讯录中就会产出现双发的姓名。

bubuko.com,布布扣bubuko.com,布布扣




可以试想双方的通信,如果再启动客户端也可以进行三方通信,可以使用表情的添加,以及记录的删除。

bubuko.com,布布扣bubuko.com,布布扣




  这个是朋友圈,你可以给你的朋友发送信息,同时可以赞,也可以发表自己的评论,别人可以看到你发的评论。

bubuko.com,布布扣bubuko.com,布布扣



服务器端主要源码:


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




使用xsocket框架实现的Android即时通讯软件

标签:android   即时通讯   application   xsocket   xstream   

原文地址:http://blog.csdn.net/kai46385076/article/details/41551609

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!