即时通讯之smack客户端配置
之前学习了通过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;
}
}
主要还是通过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;
}
}
作者:KeerDi —— 北方的后生
出处:http://www.cnblogs.com/keerdi/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。