之前学习了通过Openfire+spark+smack的模式来完成我们的即时通讯软件,上次我们已经完成了Openfire的安装和配置,这次我们继续完成我们的客户端部分。

  1.首先我们通过百度smack来下载我们所需要的jar包,将下载好的jar包导入到我们的工程中,创建一个工具类XmppTool:

package com.xmpp.client.util;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.json.JSONArray; public class XmppTool { private static XMPPConnection con = null; private static void openConnection(String url, String pcName) {
try {
// url、端口,也可以设置连接的服务器名字,地址,端口,用户。
ConnectionConfiguration connConfig = new ConnectionConfiguration(
"192.168.2.113", 5222, "JEREHEDU"); con = new XMPPConnection(connConfig);
con.connect();
} catch (XMPPException xe) {
xe.printStackTrace();
}
} private static void openOffConnection(String url, String pcName) {
try {
ConnectionConfiguration connConfig = new ConnectionConfiguration(
url, 5222, pcName);
connConfig.setSendPresence(false);
con = new XMPPConnection(connConfig);
con.connect();
} catch (XMPPException xe) {
xe.printStackTrace();
}
} public static XMPPConnection getOffConnection(String url, String pcName) {
if (con == null) { openOffConnection(url, pcName);
}
return con;
} public static XMPPConnection getConnection(String url, String pcName) {
if (con == null) {
openConnection(url, pcName);
}
return con;
} public static void closeConnection() {
con.disconnect();
con = null;
}
}

工具类XmppTool

  主要还是通过ConnectionConfiguration来连接服务器,传入三个参数(地址,端口,用户名)

  2.登陆界面

package com.xmpp.client;

import java.util.Iterator;

import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.OfflineMessageManager; import com.xmpp.client.util.XmppTool;
import com.xmpp.client.R; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast; public class FormLogin extends Activity implements OnClickListener { private EditText useridText, pwdText, urlText, pcnameText;;
private LinearLayout layout1, layout2; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.formlogin); // 获取用户和密码
this.useridText = (EditText) findViewById(R.id.formlogin_userid);
this.pwdText = (EditText) findViewById(R.id.formlogin_pwd);
this.urlText = (EditText) findViewById(R.id.formlogin_url);
this.pcnameText = (EditText) findViewById(R.id.formlogin_pcname);
// 正在登录
this.layout1 = (LinearLayout) findViewById(R.id.formlogin_layout1);
// 登录界面
this.layout2 = (LinearLayout) findViewById(R.id.formlogin_layout2); Button btsave = (Button) findViewById(R.id.formlogin_btsubmit);
btsave.setOnClickListener(this);
Button btcancel = (Button) findViewById(R.id.formlogin_btcancel);
btcancel.setOnClickListener(this);
} @Override
public void onClick(View v) {
// 根据ID来进行提交或者取消
switch (v.getId()) {
case R.id.formlogin_btsubmit:
// 取得填入的用户和密码
// 取得填入的用户和密码
final String USERID = this.useridText.getText().toString();
final String PWD = this.pwdText.getText().toString();
final String URL = this.urlText.getText().toString();
final String PCNAME = this.pcnameText.getText().toString(); Thread t = new Thread(new Runnable() {
public void run() {
// sendEmptyMessage:发送一条消息
handler.sendEmptyMessage(1);
try {
// 连接
XmppTool.getOffConnection(URL, PCNAME).login(USERID,
PWD);
getOfflineMessage();
// 状态
Presence presence = new Presence(
Presence.Type.available);
XmppTool.getConnection(URL, PCNAME)
.sendPacket(presence); Intent intent = new Intent();
intent.setClass(FormLogin.this, FormClient.class);
intent.putExtra("USERID", USERID);
intent.putExtra("URL", URL);
intent.putExtra("PCNAME", PCNAME);
FormLogin.this.startActivity(intent);
FormLogin.this.finish();
} catch (XMPPException e) {
XmppTool.closeConnection(); handler.sendEmptyMessage(2);
}
}
});
t.start();
break;
case R.id.formlogin_btcancel:
finish();
break;
}
} /**
* 获取离线消息
*/
private void getOfflineMessage() { OfflineMessageManager offlineManager = new OfflineMessageManager(
XmppTool.getConnection(this.urlText.getText().toString(),
this.pcnameText.getText().toString()));
Iterator<org.jivesoftware.smack.packet.Message> it;
try {
it = offlineManager.getMessages();
while (it.hasNext()) {
org.jivesoftware.smack.packet.Message message = it.next();
Log.i("离线消息", "收到离线消息, Received from 【" + message.getFrom()
+ "】 message: " + message.getBody());
}
// 删除离线消息
offlineManager.deleteMessages(); } catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) { if (msg.what == 1) {
layout1.setVisibility(View.VISIBLE);
layout2.setVisibility(View.GONE);
} else if (msg.what == 2) {
layout1.setVisibility(View.GONE);
layout2.setVisibility(View.VISIBLE);
Toast.makeText(FormLogin.this, "登录失败!", Toast.LENGTH_SHORT)
.show();
}
};
};
}

登陆界面

  3.聊天客户端

package com.xmpp.client;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List; import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.filetransfer.FileTransfer;
import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.packet.DelayInformation; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest.HttpMethod; import com.xmpp.client.util.ScreenShot;
import com.xmpp.client.util.TimeRender;
import com.xmpp.client.util.XmppTool; public class FormClient extends Activity { private MyAdapter adapter;
private List<Msg> listMsg = new ArrayList<Msg>();
private String pUSERID;
private EditText msgText, toText;
private ProgressBar pb; private Button btsend; private TextView waitpb; private String URL;
private String PCNAME;
private String PERSON; private Chat mychat;
private ChatManager cm; public class Msg {
String userid;
String msg;
String date;
String from; public Msg(String userid, String msg, String date, String from) {
this.userid = userid;
this.msg = msg;
this.date = date;
this.from = from;
}
} @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.formclient); // 获取Intent传过来的用户名,url,pcname
this.pUSERID = getIntent().getStringExtra("USERID");
this.URL = getIntent().getStringExtra("URL");
this.PCNAME = getIntent().getStringExtra("PCNAME"); ListView listview = (ListView) findViewById(R.id.formclient_listview);
listview.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); this.adapter = new MyAdapter(this);
listview.setAdapter(adapter); // 获取文本信息
this.msgText = (EditText) findViewById(R.id.formclient_text);
// 获取聊天对象
this.toText = (EditText) findViewById(R.id.formclient_to); // 发送消息给water-pc服务器water(获取自己的服务器,和好友)
// 消息监听
cm = XmppTool.getConnection(URL, PCNAME).getChatManager();
chatListener(); // 发送消息
btsend = (Button) findViewById(R.id.formclient_btsend);
sendChatMessage(); } /**
* send chat message
*
*/
private void sendChatMessage() {
btsend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 获取text文本
String msg = msgText.getText().toString();
PERSON = toText.getText().toString();
mychat = cm.createChat(PERSON + "@" + PCNAME, null);
if (msg.length() > 0) {
// 发送消息
listMsg.add(new Msg(pUSERID, msg, TimeRender.getDate(),
"OUT"));
// 刷新适配器
adapter.notifyDataSetChanged();
try {
// 发送消息给指定人
mychat.sendMessage(msg); } catch (XMPPException e) {
e.printStackTrace();
}
} else {
Toast.makeText(FormClient.this, "请输入信息", Toast.LENGTH_SHORT)
.show();
}
// 清空text
msgText.setText("");
}
});
} /**
* 监听单人消息
*/
private void chatListener() {
cm.addChatListener(new ChatManagerListener() {
@Override
public void chatCreated(Chat chat, boolean able) {
chat.addMessageListener(new MessageListener() {
@Override
public void processMessage(Chat chat2, Message message) {
Log.v("--tags--", "--tags-form--" + message.getFrom());
Log.v("--tags--",
"--tags-message--" + message.getBody()); // 收到来自water-pc服务器water的消息(获取自己的服务器,和好友)
if (message.getFrom().contains(pUSERID + "@keyi-pc")) {
// 获取用户、消息、时间、IN
String[] args = new String[] { pUSERID,
message.getBody(), TimeRender.getDate(),
"IN" };
android.os.Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = args;
msg.sendToTarget();
} else { } Log.i("json", "b " + message.getBody());
String amsg = message.getBody();
String[] args = null; args = new String[] { message.getFrom(), amsg,
TimeRender.getDate(), "IN" };
android.os.Message msg = handler
.obtainMessage();
msg.what = 1;
msg.obj = args;
msg.sendToTarget(); } });
}
});
} private OutgoingFileTransfer fileTransfer; Handler outHandler = new Handler();
Runnable outrunnable = new Runnable() {
@Override
public void run() {
if (fileTransfer.getProgress() == 1) {
pb.setVisibility(View.GONE);
outHandler.removeCallbacks(outrunnable);
}
outHandler.postDelayed(outrunnable, 100); }
}; private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) { switch (msg.what) {
case 1:
// 获取消息并显示
String[] args = (String[]) msg.obj;
listMsg.add(new Msg(args[0], args[1], args[2], args[3]));
// 刷新适配器
adapter.notifyDataSetChanged();
break;
case 2:
// 附件进度条
if (pb.getVisibility() == View.GONE) { pb.setVisibility(View.VISIBLE);
waitpb.setVisibility(View.VISIBLE);
}
break;
case 3:
pb.setProgress(msg.arg1);
break;
case 4:
pb.setVisibility(View.GONE);
waitpb.setVisibility(View.GONE);
break; default:
break;
}
};
}; // 退出
@Override
public void onBackPressed() {
super.onBackPressed();
XmppTool.closeConnection();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
} class MyAdapter extends BaseAdapter { private Context cxt;
private LayoutInflater inflater; public MyAdapter(FormClient formClient) {
this.cxt = formClient;
} @Override
public int getCount() {
return listMsg.size();
} @Override
public Object getItem(int position) {
return listMsg.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// 显示消息的布局:内容、背景、用户、时间
this.inflater = (LayoutInflater) this.cxt
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // IN,OUT的图片
if (listMsg.get(position).from.equals("IN")) {
convertView = this.inflater.inflate(
R.layout.formclient_chat_in, null);
} else {
convertView = this.inflater.inflate(
R.layout.formclient_chat_out, null);
} TextView useridView = (TextView) convertView
.findViewById(R.id.formclient_row_userid);
TextView dateView = (TextView) convertView
.findViewById(R.id.formclient_row_date);
TextView msgView = (TextView) convertView
.findViewById(R.id.formclient_row_msg); useridView.setText(listMsg.get(position).userid);
dateView.setText(listMsg.get(position).date);
msgView.setText(listMsg.get(position).msg); return convertView;
}
} }

聊天客户端

  其中有好多类都是自带的我们只需要实现它就可以了。

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

即时通讯之smack客户端配置的更多相关文章

  1. nodejs+expressjs+ws实现了websocket即时通讯,服务器和客户端互相通信

    nodejs代码 // 导入WebSocket模块: const WebSocket = require('ws'); // 引用Server类: const WebSocketServer = We ...

  2. layim即时通讯实例各功能整合

    一.系统演示1.1 聊天窗体主界面演示 1.2 模拟两人在线聊天(点击图片查看演示视频) 1.3 在线演示> 在线演示,点击进入系统到这里,若是您想要的,接下来听我娓娓道来二.开发工具开发软件: ...

  3. XMPP之ios即时通讯客户端开发-配置XMPP基本信息之工程代码(五)

    登录功能完成以后包含以下代码文件: AppDelegate.h AppDelegate.m LoginViewController.h LoginViewController.m LoginUser. ...

  4. 用smack+openfire做即时通讯

    首发:个人博客 必须说明:smack最新的4.1.1,相对之前版本变化很大,而且资料缺乏,官方文档也不好,所以还是用老版本3.2.2吧.这篇博文中的代码是4.1.1版的,但不推荐用它.用openfir ...

  5. openfire+spark+smack实现即时通讯

    近公司项目需要用到即时通讯功能,经过调研发现openfire+spark+smack可以实现.在网上找了很久,资料都十分有限,即使有些朋友实现了也说的不清不楚.于是决定自己研究,耗时一周的时间实现了文 ...

  6. openfire+smack 实现即时通讯基本框架

    smack jar下载地址 http://www.igniterealtime.org/downloads/download-landing.jsp?file=smack/smack_3_2_2.zi ...

  7. XMPP openfire Smack 即时通讯

    重新整理下这篇文章. 这篇文章的主要任务是使用AndroidStudio,通过Openfire,利用XMPP协议完成一个可以即时通讯.拥有好友系统的聊天软件. 一.服务器配置与相关库 理论不多说,只谈 ...

  8. Openfire XMPP Smack RTC IM 即时通讯 聊天 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. 基于openfire+smack即时通讯instant message开发

    前言 Java领域的即时通信的解决方案可以考虑openfire+spark+smack.当然也有其他的选择. Openfire 是基于Jabber协议(XMPP)实现的即时通信服务器端版本,目前建议使 ...

随机推荐

  1. [leetcode tree]107. Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...

  2. 1036 Boys vs Girls (25)(25 point(s))

    problem This time you are asked to tell the difference between the lowest grade of all the male stud ...

  3. python抓包模块

    pcapy模块 安装 yum install -y epel-release yum install -y pip gcc    gcc-c++   libpcap-devel python-deve ...

  4. Alpha7

    难受

  5. java线程系列文章之一(线程的安全性)

    本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7421217,转载请注明. 当我们查看JDK API的时候,总会发现一些类 ...

  6. 【BZOJ】4260: Codechef REBXOR【Trie树】【前后缀异或最大】

    4260: Codechef REBXOR Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2218  Solved: 962[Submit][Stat ...

  7. Android之基于HTTP协议的通信详解

    Android系统中本身是有下载机制的,比如浏览器使用的DownloadManager.可遗憾的是,DownloadManager只提供给浏览器使用,一般的应用程序没法调用它. 另外,如果下载调用频繁 ...

  8. CI下php操作memcached 的问题

    CI下php操作memcached 的时候,获取memcached里不存在的key时候,会出错,然而放在程序的最后一行就不会出错,不知何故,mark一下.

  9. Java线程锁&分布式锁的理解及应用

    了解Java线程锁之前,先理解线程和进程的定义.进程是操作系统分配资源(CPU)的基本单位,线程是CPU执行的基本单位,一个进程可拥有多个线程,同进程间的多个线程共享分配给进程的资源.比如启动JVM时 ...

  10. SCSI Pass-Through Interface Tool

    http://code.msdn.microsoft.com/SCSI-Pass-Through-a906ceef/sourcecode?fileId=59048&pathId=1919073 ...