package com.openims.service; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.Future; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.smack.RosterGroup; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.MessageTypeFilter; import org.jivesoftware.smack.filter.NotFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Registration; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError.Type; import org.jivesoftware.smack.provider.PrivacyProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smackx.GroupChatInvitation; import org.jivesoftware.smackx.PrivateDataManager; import org.jivesoftware.smackx.ServiceDiscoveryManager; import org.jivesoftware.smackx.filetransfer.FileTransfer; import org.jivesoftware.smackx.filetransfer.FileTransferManager; import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer; import org.jivesoftware.smackx.packet.ChatStateExtension; import org.jivesoftware.smackx.packet.DiscoverItems; import org.jivesoftware.smackx.packet.LastActivity; import org.jivesoftware.smackx.packet.OfflineMessageInfo; import org.jivesoftware.smackx.packet.OfflineMessageRequest; import org.jivesoftware.smackx.packet.SharedGroupsInfo; import org.jivesoftware.smackx.packet.VCard; import org.jivesoftware.smackx.packet.DiscoverItems.Item; import org.jivesoftware.smackx.provider.AdHocCommandDataProvider; import org.jivesoftware.smackx.provider.BytestreamsProvider; import org.jivesoftware.smackx.provider.DataFormProvider; import org.jivesoftware.smackx.provider.DelayInformationProvider; import org.jivesoftware.smackx.provider.DiscoverInfoProvider; import org.jivesoftware.smackx.provider.DiscoverItemsProvider; import org.jivesoftware.smackx.provider.IBBProviders; import org.jivesoftware.smackx.provider.MUCAdminProvider; import org.jivesoftware.smackx.provider.MUCOwnerProvider; import org.jivesoftware.smackx.provider.MUCUserProvider; import org.jivesoftware.smackx.provider.MessageEventProvider; import org.jivesoftware.smackx.provider.MultipleAddressesProvider; import org.jivesoftware.smackx.provider.RosterExchangeProvider; import org.jivesoftware.smackx.provider.StreamInitiationProvider; import org.jivesoftware.smackx.provider.VCardProvider; import org.jivesoftware.smackx.provider.XHTMLExtensionProvider; import org.jivesoftware.smackx.pubsub.AccessModel; import org.jivesoftware.smackx.pubsub.ConfigureForm; import org.jivesoftware.smackx.pubsub.FormType; import org.jivesoftware.smackx.pubsub.LeafNode; import org.jivesoftware.smackx.pubsub.Node; import org.jivesoftware.smackx.pubsub.PayloadItem; import org.jivesoftware.smackx.pubsub.PubSubManager; import org.jivesoftware.smackx.pubsub.PublishModel; import org.jivesoftware.smackx.pubsub.SimplePayload; import org.jivesoftware.smackx.pubsub.Subscription; import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; import org.jivesoftware.smackx.pubsub.provider.SubscriptionProvider; import org.jivesoftware.smackx.search.UserSearch; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Handler; import android.util.Log; import com.openims.model.MyApplication; import com.openims.model.chat.RosterDataBase; import com.openims.model.chat.VCardDataBase; import com.openims.service.chat.ChatPacketListener; import com.openims.service.chat.MyRosterListener; import com.openims.service.chat.PresenceListener; import com.openims.service.connection.ConnectivityReceiver; import com.openims.service.connection.PersistentConnectionListener; import com.openims.service.fileTransfer.FileReceiver; import com.openims.service.notificationPacket.NotificationIQ; import com.openims.service.notificationPacket.NotificationIQProvider; import com.openims.service.notificationPacket.NotificationPacketListener; import com.openims.service.notificationPacket.RegPushIQ; import com.openims.service.notificationPacket.RegPushPacketListener; import com.openims.service.notificationPacket.RegPushProvider; import com.openims.service.notificationPacket.UserQueryIQ; import com.openims.service.pubsub.SubListener; import com.openims.utility.DeviceFun; import com.openims.utility.LogUtil; import com.openims.utility.PushServiceUtil; import com.smit.EasyLauncher.R; /** * This class deal with login logout send message and broadcast * it is smack center * @author ANDREW CHAN (chenyzpower@gmail.com) * */ public class XmppManager{ private static final String LOGTAG = LogUtil.makeLogTag(XmppManager.class); private static final String TAG = LogUtil.makeTag(XmppManager.class); /** * login information */ private String xmppHost; private int xmppPort; private String username; private String password; private String resource = null; private String mAdminJid; private SharedPreferences sharedPrefs; private String mRegUsername; private String mRegPassword; private XMPPConnection connection; private IMService imservice; private IMService.TaskSubmitter taskSubmitter; private IMService.TaskTracker taskTracker; private BroadcastReceiver connectivityReceiver; // TODO ��Ҫ�Ż����ߺʹ�����������ͷ�һ����Դ private List<Runnable> taskList; private boolean running = false; private Future<?> futureTask; private Thread reconnection = null; int reconnectTime = 0; private Handler handler; /** * register XMPP handle listener */ private ConnectionListener connectionListener; private PacketListener notificationPacketListener; private PacketListener regPushPacketListener; private FileTransferManager fileTransferManager; /** * publish subscription */ private Map<String,LeafNode> topicMap = null; public XmppManager(IMService imservice){ this.imservice = imservice; taskSubmitter = imservice.getTaskSubmitter(); taskTracker = imservice.getTaskTracker(); sharedPrefs = imservice.getSharedPreferences(); initUserInf(); connectionListener = new PersistentConnectionListener(this); notificationPacketListener = new NotificationPacketListener(this); regPushPacketListener = new RegPushPacketListener(this); handler = new Handler(); taskList = new ArrayList<Runnable>(); topicMap = new HashMap<String,LeafNode>(); configure(ProviderManager.getInstance()); } public void initUserInf(){ xmppHost = sharedPrefs.getString(PushServiceUtil.XMPP_HOST, "localhost"); xmppPort = sharedPrefs.getInt(PushServiceUtil.XMPP_PORT, 5222); username = sharedPrefs.getString(PushServiceUtil.XMPP_USERNAME, ""); password = sharedPrefs.getString(PushServiceUtil.XMPP_PASSWORD, ""); resource = sharedPrefs.getString(PushServiceUtil.XMPP_RESOURCE, ""); } /** * dynamic create resource * @return */ public String getResource(){ if(resource == null || resource.length()==0){ resource = newRandomUUID(); Editor editor = sharedPrefs.edit(); editor.putString(PushServiceUtil.XMPP_RESOURCE, resource); editor.commit(); } return this.resource; } public void connect() { Log.d(LOGTAG, "connect()..."); submitLoginTask(); } /** * log out */ public void disconnect() { Log.d(LOGTAG, "disconnect()..."); if(connectivityReceiver != null){ imservice.unregisterReceiver(connectivityReceiver); connectivityReceiver = null; } RosterDataBase rosterDataBase = new RosterDataBase(this.imservice,mAdminJid); rosterDataBase.removeAll(); // delete all rosterDataBase.close(); if (getConnection() != null && getConnection().isConnected()) { Presence presence = new Presence(Presence.Type.unavailable); connection.sendPacket(presence); getConnection().disconnect(); } stopReconnectionThread(); terminatePersistentConnection(); broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGOUT); } public void reregisterAccount() { removeAccount(); submitLoginTask(); runTask(); } private void terminatePersistentConnection() { Log.d(LOGTAG, "terminatePersistentConnection()..."); Runnable runnable = new Runnable() { final XmppManager xmppManager = XmppManager.this; public void run() { if (xmppManager.isConnected()) { Log.d(LOGTAG, "terminatePersistentConnection()... run()"); xmppManager.getConnection().removePacketListener( xmppManager.getNotificationPacketListener()); xmppManager.getConnection().disconnect(); } // TODO-ANDREW should end reconnection thread xmppManager.runTask(); } }; addTask(runnable); } public void sendChatMessage(String to, String mesContent){ Message msg = new Message(to, Message.Type.chat); msg.setBody(mesContent); Log.i(LOGTAG, to +" send msg:" + mesContent); sendPacket(msg); } public void sendPacket(Packet packet){ if(this.isAuthenticated()) connection.sendPacket(packet); else broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_FAIL); } public void startReconnectionThread() { /*synchronized (reconnection) { if (!reconnection.isAlive()) { reconnection.setName("Xmpp Reconnection Thread"); reconnection.start(); } }*/ //reconnection = new ReconnectionThread(this); //reconnection.start(); //increaseReconnectTime(); } private void stopReconnectionThread(){ if(reconnection==null) return; synchronized (reconnection) { reconnection.interrupt(); } } private void increaseReconnectTime(){ reconnectTime =+ 3; if(reconnectTime > 30){ reconnectTime = 30; } } private void resetReconnectTime(){ reconnectTime = 0; } private void clearTask(){ taskList.clear(); taskTracker.count = 0; running = false; } private void runTask() { Log.d(LOGTAG, "runTask()..."); synchronized (taskList) { running = false; futureTask = null; if (!taskList.isEmpty()) { Runnable runnable = (Runnable) taskList.get(0); taskList.remove(0); running = true; futureTask = taskSubmitter.submit(runnable); if (futureTask == null) { taskTracker.decrease(); } } } taskTracker.decrease(); Log.d(LOGTAG, "runTask()...done"); } public PacketListener getNotificationPacketListener() { return notificationPacketListener; } public PacketListener getRegPushPacketListener(){ return regPushPacketListener; } public Context getContext(){ return imservice; } public XMPPConnection getConnection() { return connection; } private void setConnection(XMPPConnection connection) { this.connection = connection; } public String getUserNameWithHostName(){ return mAdminJid; } private void setUsername(String username) { this.username = username; } private String getPassword() { return password; } private void setPassword(String password) { this.password = password; } /** * for reconnection * @return */ public Handler getHandler() { return handler; } public ConnectionListener getConnectionListener() { return connectionListener; } private String newRandomUUID() { String uuidRaw = UUID.randomUUID().toString(); return uuidRaw.replaceAll("-", ""); } private boolean isConnected() { return connection != null && connection.isConnected(); } public boolean isAuthenticated() { return connection != null && connection.isConnected() && connection.isAuthenticated(); } private boolean isRegistered() { return sharedPrefs.contains(PushServiceUtil.XMPP_USERNAME) && sharedPrefs.contains(PushServiceUtil.XMPP_PASSWORD); } private void removeAccount() { Editor editor = sharedPrefs.edit(); editor.remove(PushServiceUtil.XMPP_USERNAME); editor.remove(PushServiceUtil.XMPP_PASSWORD); editor.commit(); } private void submitConnectTask() { Log.d(LOGTAG, "submitConnectTask()..."); addTask(new ConnectTask()); } private void submitRegisterTask() { Log.d(LOGTAG, "submitRegisterTask()..."); submitConnectTask(); addTask(new RegisterTask()); } private void submitLoginTask() { Log.d(LOGTAG, "submitLoginTask()..."); submitRegisterTask(); addTask(new LoginTask()); } private void addTask(Runnable runnable) { Log.d(LOGTAG, "addTask(runnable)..."); taskTracker.increase(); synchronized (taskList) { // ��������б�Ϊ�գ�ͬʱû�ж��������У��Ϳ�ʼ���� if (taskList.isEmpty() && !running) { running = true; futureTask = taskSubmitter.submit(runnable); if (futureTask == null) { taskTracker.decrease(); } } else { taskList.add(runnable); } } Log.d(LOGTAG, "addTask(runnable)... done"); } /** * A runnable task to connect the server. */ private class ConnectTask implements Runnable { final XmppManager xmppManager; private ConnectTask() { this.xmppManager = XmppManager.this; } public void run() { Log.i(LOGTAG, "ConnectTask.run()..."); if (!xmppManager.isConnected()) { // Create the configuration for this new connection ConnectionConfiguration connConfig = new ConnectionConfiguration( xmppHost, xmppPort); connConfig.setSecurityMode(SecurityMode.disabled); // connConfig.setSecurityMode(SecurityMode.required); connConfig.setSASLAuthenticationEnabled(false); connConfig.setCompressionEnabled(false); connConfig.setReconnectionAllowed(true); XMPPConnection connection = new XMPPConnection(connConfig); xmppManager.setConnection(connection); try { // Connect to the server Log.i(LOGTAG, "Start to connect..."); connection.connect(); Log.i(LOGTAG, "XMPP connected successfully"); // Set the status to available Log.i(LOGTAG, TAG+"set presence"); Presence presence = new Presence(Presence.Type.available); connection.sendPacket(presence); // packet provider ProviderManager.getInstance().addIQProvider("openims", "smit:iq:notification", new NotificationIQProvider()); ProviderManager.getInstance().addIQProvider("openims", "smit:iq:registerPushService", new RegPushProvider()); initPubSub(); } catch (XMPPException e) { broadcastStatus(PushServiceUtil.PUSH_STATUS_CONNECTION_FAIL); Log.e(LOGTAG, "XMPP connection failed", e); } } else { Log.i(LOGTAG, "XMPP connected already"); } xmppManager.runTask(); } } /** * A runnable task to register a new user onto the server. */ private class RegisterTask implements Runnable { final XmppManager xmppManager; private RegisterTask() { xmppManager = XmppManager.this; } public void run() { Log.i(LOGTAG, "RegisterTask.run()..."); if(!xmppManager.isConnected()) { runTask(); return; } if (!xmppManager.isRegistered()) { final String newUsername = mRegUsername; final String newPassword = mRegPassword; Registration registration = new Registration(); PacketFilter packetFilter = new AndFilter(new PacketIDFilter( registration.getPacketID()), new PacketTypeFilter( IQ.class)); PacketListener packetListener = new PacketListener() { public void processPacket(Packet packet) { Log.d("RegisterTask.PacketListener","processPacket()....."); Log.d("RegisterTask.PacketListener", "packet=" + packet.toXML()); if (packet instanceof IQ) { IQ response = (IQ) packet; if (response.getType() == IQ.Type.ERROR) { if (response.getError().getCode() ==409) { Log.e(LOGTAG, "Unknown error while registering XMPP account! " + response.getError().getCondition()); broadcastStatus(PushServiceUtil.PUSH_STATUS_HAVEREGISTER); }else{ broadcastStatus(PushServiceUtil.PUSH_STATUS_REGISTER_FAIL); } } else if (response.getType() == IQ.Type.RESULT) { xmppManager.setUsername(newUsername); xmppManager.setPassword(newPassword); Log.d(LOGTAG, "username=" + newUsername); Log.d(LOGTAG, "password=" + newPassword); Editor editor = sharedPrefs.edit(); editor.putString(PushServiceUtil.XMPP_USERNAME, newUsername); editor.putString(PushServiceUtil.XMPP_PASSWORD, newPassword); editor.commit(); Log.i(LOGTAG,"Account registered successfully"); broadcastStatus(PushServiceUtil.PUSH_STATUS_REGISTER_SUC); } } xmppManager.runTask(); } }; connection.addPacketListener(packetListener, packetFilter); registration.setType(IQ.Type.SET); registration.addAttribute("username", newUsername); registration.addAttribute("password", newPassword); connection.sendPacket(registration); } else { Log.i(LOGTAG, "Account registered already"); xmppManager.runTask(); } } } /** * A runnable task to log into the server. */ private class LoginTask implements Runnable { final XmppManager xmppManager; private LoginTask() { this.xmppManager = XmppManager.this; } public void run() { Log.i(LOGTAG, "LoginTask.run()..."); if(!xmppManager.isConnected()) { runTask(); return; } if (!xmppManager.isAuthenticated()) { Log.d(LOGTAG, "username=" + username); Log.d(LOGTAG, "password=" + password); try { xmppManager.getConnection().login( xmppManager.username, xmppManager.getPassword(), getResource()); Log.d(LOGTAG, "Loggedn in successfully"); initAfterLogin(); broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_SUC); } catch (XMPPException e) { Log.e(LOGTAG, "LoginTask.run()... xmpp error"); Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: "+ e.getMessage()); broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_FAIL); String INVALID_CREDENTIALS_ERROR_CODE = "401"; String errorMessage = e.getMessage(); if (errorMessage != null && errorMessage.contains(INVALID_CREDENTIALS_ERROR_CODE)) { broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_UNREG); xmppManager.clearTask(); return; } } catch (Exception e) { Log.e(LOGTAG, "LoginTask.run()... other error"); Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: " + e.getMessage()); broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_FAIL); } } else { Log.i(LOGTAG, "Logged in already"); broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_SUC); } xmppManager.runTask(); } } public void registerAccount(String userName,String psw){ mRegUsername = userName; mRegPassword = psw; removeAccount(); submitRegisterTask(); runTask(); //Collection<String> a = connection.getAccountManager().getAccountAttributes(); } public void broadcastStatus(String inf){ Intent intentSend = new Intent(PushServiceUtil.ACTION_STATUS); intentSend.putExtra(PushServiceUtil.PUSH_STATUS, inf); imservice.sendBroadcast(intentSend); } public void notifyNewMessage(String jid){ imservice.setOneUnreadMessage(jid); } public void notifyRosterUpdated(String jid){ imservice.notifyRosterUpdated(jid); } private void initPubSub(){ ProviderManager pm = ProviderManager.getInstance(); pm.addIQProvider( "query", "http://jabber.org/protocol/disco#items", new org.jivesoftware.smackx.provider.DiscoverItemsProvider() ); pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new org.jivesoftware.smackx.provider.DiscoverInfoProvider()); pm.addIQProvider("pubsub", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.PubSubProvider()); pm.addExtensionProvider("subscription", PubSubNamespace.BASIC.getXmlns() , new SubscriptionProvider()); pm.addExtensionProvider( "create", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.SimpleNodeProvider()); pm.addExtensionProvider("items", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.ItemsProvider()); pm.addExtensionProvider("item", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.ItemProvider()); pm.addExtensionProvider("item", "", new org.jivesoftware.smackx.pubsub.provider.ItemProvider()); pm.addExtensionProvider( "subscriptions", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.SubscriptionsProvider()); pm.addExtensionProvider( "subscriptions", "http://jabber.org/protocol/pubsub#owner", new org.jivesoftware.smackx.pubsub.provider.SubscriptionsProvider()); pm.addExtensionProvider( "affiliations", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.AffiliationsProvider()); pm.addExtensionProvider( "affiliation", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.AffiliationProvider()); pm.addExtensionProvider("options", "http://jabber.org/protocol/pubsub", new org.jivesoftware.smackx.pubsub.provider.FormNodeProvider()); pm.addIQProvider("pubsub", "http://jabber.org/protocol/pubsub#owner", new org.jivesoftware.smackx.pubsub.provider.PubSubProvider()); pm.addExtensionProvider("configure", "http://jabber.org/protocol/pubsub#owner", new org.jivesoftware.smackx.pubsub.provider.FormNodeProvider()); pm.addExtensionProvider("default", "http://jabber.org/protocol/pubsub#owner", new org.jivesoftware.smackx.pubsub.provider.FormNodeProvider()); pm.addExtensionProvider("event", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.EventProvider()); pm.addExtensionProvider( "configuration", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.ConfigEventProvider()); pm.addExtensionProvider( "delete", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.SimpleNodeProvider()); pm.addExtensionProvider("options", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.FormNodeProvider()); pm.addExtensionProvider("items", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.ItemsProvider()); pm.addExtensionProvider("item", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.ItemProvider()); pm.addExtensionProvider("headers", "http://jabber.org/protocol/shim", new org.jivesoftware.smackx.provider.HeaderProvider()); pm.addExtensionProvider("header", "http://jabber.org/protocol/shim", new org.jivesoftware.smackx.provider.HeadersProvider()); pm.addExtensionProvider( "retract", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.RetractEventProvider()); pm.addExtensionProvider( "purge", "http://jabber.org/protocol/pubsub#event", new org.jivesoftware.smackx.pubsub.provider.SimpleNodeProvider()); pm.addExtensionProvider( "x", "jabber:x:data", new org.jivesoftware.smackx.provider.DataFormProvider()); } private List<String> getTopicNode(){ PubSubManager manager = new PubSubManager(connection, "pubsub.smitnn"); List<String> nodes = new LinkedList<String>(); try { DiscoverItems dItems = manager.discoverNodes(null); Iterator<Item> it = dItems.getItems(); Item item; while(it.hasNext()){ item = it.next(); Log.d(LOGTAG,TAG+item.toXML()); nodes.add(item.getNode()); } } catch (XMPPException e) { // TODO Auto-generated catch block e.printStackTrace(); } return nodes; } private boolean listenTopic(List<String> topics){ boolean b = true; topicMap.clear(); StringBuilder user = new StringBuilder(connection.getUser().trim()); user.delete(user.lastIndexOf("/"), user.length()); for(int i=0;i<topics.size();i++){ PubSubManager manager = new PubSubManager(connection,"pubsub.smitnn"); LeafNode leafNode = null; try { String topic = topics.get(i); Node node = manager.getNode(topic); if(node == null){ b = false; continue; } node.subscribe(user.toString()); node.addItemEventListener( new SubListener(XmppManager.this,topic)); leafNode = (LeafNode)node; topicMap.put(topic, leafNode); leafNode = null; Log.d(LOGTAG,TAG+"subscription topic:" + topic); } catch(XMPPException e1){ e1.printStackTrace(); b = false; } catch(Exception e){ e.printStackTrace(); b = false; } } return b; } private LeafNode getLeafNode(String topic){ LeafNode leafNode = null; PubSubManager manager = new PubSubManager(connection,"pubsub.smitnn"); Log.i(LOGTAG,TAG+connection.getHost()); try { Node node = manager.getNode(topic); leafNode = (LeafNode)node; } catch(XMPPException e1){ e1.printStackTrace(); XMPPError error = e1.getXMPPError(); Type type = error.getType(); try { ConfigureForm f = new ConfigureForm(FormType.submit); f.setDeliverPayloads(true); f.setAccessModel(AccessModel.open); f.setPublishModel(PublishModel.open); f.setSubscribe(true); f.setPersistentItems(true); Node eventNode = manager.createNode(topic,f); leafNode = (LeafNode)eventNode; Log.d(LOGTAG,TAG+"create new node "+topic); } catch (XMPPException e2) { e2.printStackTrace(); return null; } } leafNode.addItemEventListener( new SubListener(XmppManager.this)); // you will need this first time only try { StringBuilder user = new StringBuilder(connection.getUser().trim()); user.delete(user.lastIndexOf("/"), user.length()); Subscription sst = leafNode.subscribe(user.toString()); Log.d(LOGTAG,TAG+connection.getUser()+"subscription"); } catch (XMPPException e1) { // TODO Auto-generated catch block e1.printStackTrace(); System.out.println("XMPPClient errore durante la subscribe al nodo"+ e1.toString()); } return leafNode; } public void sendTopic(String topic,String message){ sendFile(); if(message.equals("hello")) return; if(!this.isAuthenticated()){ broadcastStatus(PushServiceUtil.PUSH_STATUS_LOGIN_FAIL); return; } LeafNode leafNode = (LeafNode)topicMap.get(topic); if(leafNode==null){ leafNode = getLeafNode(topic); if(leafNode == null){ Log.e(LOGTAG,TAG+"can't get topic" + topic); return; }else{ topicMap.put(topic, leafNode); } } SimplePayload payload = new SimplePayload("event", null, "<all>" + message + "</all>"); PayloadItem payloadItem = new PayloadItem(null, payload); try { leafNode.send(payloadItem); Log.d(LOGTAG,TAG+"Send info" + message); } catch (XMPPException e) { e.printStackTrace(); broadcastStatus(PushServiceUtil.PUSH_STATUS_SENDFAIL); // ����ʧ�� } } private void initAfterLogin(){ // get server name String serverName = getConnection().getServiceName(); mAdminJid = username + "@"+serverName; Editor editor = sharedPrefs.edit(); editor.putString(PushServiceUtil.XMPP_HOSTNAME,"@"+serverName); editor.commit(); getRoster(); // connection listener if (getConnectionListener() != null) { getConnection().addConnectionListener( getConnectionListener()); } // packet filter // packet listener PacketFilter packetFilter = new PacketTypeFilter( NotificationIQ.class); PacketListener packetListener = getNotificationPacketListener(); connection.addPacketListener(packetListener, packetFilter); PacketFilter packetFilter2 = new PacketTypeFilter( RegPushIQ.class); PacketListener packetListener2 = getRegPushPacketListener(); connection.addPacketListener(packetListener2, packetFilter2); PacketFilter chatFilter = new MessageTypeFilter(Message.Type.chat); ChatPacketListener chatListener = new ChatPacketListener(this); connection.addPacketListener(chatListener, chatFilter); PacketFilter presenceFilter = new PacketTypeFilter(Presence.class); PresenceListener presenceListener = new PresenceListener(this); connection.addPacketListener(presenceListener,presenceFilter); // TODO-ANDREW test need to delete NotFilter notFilter = new NotFilter(chatFilter); connection.addPacketListener(new PacketListener(){ public void processPacket(Packet packet) { Log.i(LOGTAG,TAG+"xmnl:"+packet.getXmlns() +";From:"+packet.getFrom()); Log.i(LOGTAG,TAG+packet.toXML()); } },notFilter); List<String> topics = getTopicNode(); listenTopic(topics); new ServiceDiscoveryManager(connection);//for file transfer try{ fileTransferManager = new FileTransferManager(connection); fileTransferManager.addFileTransferListener(new FileReceiver(this)); }catch(Exception e){ Log.e(LOGTAG,"get file manager listener error"); e.printStackTrace(); } String deviceName = DeviceFun.getRoomNum(imservice.getContentResolver()); // send device information to server UserQueryIQ iq = new UserQueryIQ(); iq.setDeviceId(sharedPrefs.getString(PushServiceUtil.DEVICE_ID, "")); iq.setUserAccount(mAdminJid); iq.setResource(getResource()); iq.setDeviceName(deviceName); iq.setOpCodeSave(); this.sendPacket(iq); UserQueryIQ iqQuery = new UserQueryIQ(); iq.setDeviceId(sharedPrefs.getString(PushServiceUtil.DEVICE_ID, "")); iq.setUserAccount(mAdminJid); iq.setResource(getResource()); iq.setDeviceName(deviceName); iqQuery.setOpCodeQueryOfflinePush(); this.sendPacket(iqQuery); // share connection MyApplication app = (MyApplication)this.imservice.getApplication(); app.setConnection(getConnection(),username+"@"+serverName); app.setServeName("@"+serverName); // register reconnection if(connectivityReceiver == null){ connectivityReceiver = new ConnectivityReceiver(this.imservice); IntentFilter filter = new IntentFilter(); filter.addAction(android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION); imservice.registerReceiver(connectivityReceiver, filter); } } public void updateRoster(String jid){ Roster roster = connection.getRoster(); RosterEntry entry = roster.getEntry(jid); RosterDataBase rosterDataBase = new RosterDataBase(this.imservice, mAdminJid); String presenceInf = roster.getPresence(jid).getType().name(); Collection<RosterGroup> clGroup = entry.getGroups(); Iterator<RosterGroup> iterator = clGroup.iterator(); while(iterator.hasNext()){ RosterGroup rg = iterator.next(); rosterDataBase.insert(jid, entry.getName(), rg.getName(), presenceInf); } rosterDataBase.close(); } public void deleteRoster(String jid){ RosterDataBase rosterDataBase = new RosterDataBase(this.imservice,mAdminJid); rosterDataBase.deleteRoster(jid); rosterDataBase.close(); } public void getRoster(){ Roster roster = connection.getRoster(); Collection<RosterGroup> crg = roster.getGroups(); Iterator<RosterGroup> iterator = crg.iterator(); RosterDataBase rosterDataBase = new RosterDataBase(this.imservice,mAdminJid); rosterDataBase.removeAll(); // delete all while(iterator.hasNext()){ RosterGroup rg = (RosterGroup)iterator.next(); Collection<RosterEntry> re = rg.getEntries(); Iterator<RosterEntry> iteratorEntry = re.iterator(); while(iteratorEntry.hasNext()){ RosterEntry entry = (RosterEntry)iteratorEntry.next(); String presenceInf = roster.getPresence(entry.getUser()).getType().name(); rosterDataBase.insert(entry.getUser(), entry.getName(), rg.getName(),presenceInf); } } String defaultGroupName = getContext().getResources().getString(R.string.im_default_group_name); if(rosterDataBase.isGroupNameExist(defaultGroupName) == false){ rosterDataBase.insert(mAdminJid, mAdminJid, defaultGroupName, null); } rosterDataBase.close(); roster.addRosterListener(new MyRosterListener(this)); VCardDataBase vc = new VCardDataBase(this.getContext(), this.getUserNameWithHostName()); vc.removeAll(); vc.close(); } public void getVCard(String jid) throws Exception{ VCard vcard = new VCard(); try { vcard.load(this.connection,jid); } catch (XMPPException e) { Log.e(LOGTAG,TAG+"get vcard exception"); vcard = null; e.printStackTrace(); } catch(Exception e){ e.printStackTrace(); }finally{ } VCardDataBase vc = new VCardDataBase(this.getContext(), this.getUserNameWithHostName()); if(vcard == null){ vc.insert(jid); }else{ vc.insert(jid, vcard); } vc.close(); if( vcard == null){ throw new Exception("error"); } } public void configure(ProviderManager pm) { // Private Data Storage pm.addIQProvider("query","jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider()); // Time try { pm.addIQProvider("query","jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time")); } catch (ClassNotFoundException e) { Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time"); } // Roster Exchange pm.addExtensionProvider("x","jabber:x:roster", new RosterExchangeProvider()); // Message Events pm.addExtensionProvider("x","jabber:x:event", new MessageEventProvider()); // Chat State pm.addExtensionProvider("active","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider()); pm.addExtensionProvider("composing","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider()); pm.addExtensionProvider("paused","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider()); pm.addExtensionProvider("inactive","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider()); pm.addExtensionProvider("gone","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider()); // XHTML pm.addExtensionProvider("html","http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider()); // Group Chat Invitations pm.addExtensionProvider("x","jabber:x:conference", new GroupChatInvitation.Provider()); // Service Discovery # Items pm.addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider()); // Service Discovery # Info pm.addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); // Data Forms pm.addExtensionProvider("x","jabber:x:data", new DataFormProvider()); // MUC User pm.addExtensionProvider("x","http://jabber.org/protocol/muc#user", new MUCUserProvider()); // MUC Admin pm.addIQProvider("query","http://jabber.org/protocol/muc#admin", new MUCAdminProvider()); // MUC Owner pm.addIQProvider("query","http://jabber.org/protocol/muc#owner", new MUCOwnerProvider()); // Delayed Delivery pm.addExtensionProvider("x","jabber:x:delay", new DelayInformationProvider()); // Version try { pm.addIQProvider("query","jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version")); } catch (ClassNotFoundException e) { // Not sure what's happening here. } // VCard pm.addIQProvider("vCard","vcard-temp", new VCardProvider()); // Offline Message Requests pm.addIQProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider()); // Offline Message Indicator pm.addExtensionProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider()); // Last Activity pm.addIQProvider("query","jabber:iq:last", new LastActivity.Provider()); // User Search pm.addIQProvider("query","jabber:iq:search", new UserSearch.Provider()); // SharedGroupsInfo pm.addIQProvider("sharedgroup","http://www.jivesoftware.org/protocol/sharedgroup", new SharedGroupsInfo.Provider()); // JEP-33: Extended Stanza Addressing pm.addExtensionProvider("addresses","http://jabber.org/protocol/address", new MultipleAddressesProvider()); // FileTransfer pm.addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider()); pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider()); pm.addIQProvider("open","http://jabber.org/protocol/ibb", new IBBProviders.Open()); pm.addIQProvider("close","http://jabber.org/protocol/ibb", new IBBProviders.Close()); pm.addExtensionProvider("data","http://jabber.org/protocol/ibb", new IBBProviders.Data()); // Privacy pm.addIQProvider("query","jabber:iq:privacy", new PrivacyProvider()); pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider()); pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.MalformedActionError()); pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadLocaleError()); pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadPayloadError()); pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadSessionIDError()); pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.SessionExpiredError()); } public void sendFile(){ File file = new File("/sdcard/t.txt"); long fileLen = file.length(); OutgoingFileTransfer transfer = fileTransferManager.createOutgoingFileTransfer("test2@smitnn/spark"); long timeOut = 60000; long sleepMin = 3000; long spTime = 0; int rs = 0; try { transfer.sendFile(file, "pls re file!"); } catch (XMPPException e) { // TODO Auto-generated catch block e.printStackTrace(); } rs = transfer.getStatus().compareTo(FileTransfer.Status.complete); while(rs!=0){ rs = transfer.getStatus().compareTo(FileTransfer.Status.complete); spTime = spTime + sleepMin; if(spTime>timeOut){return ;} try { Thread.sleep(sleepMin); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void setNewPushContent(){ imservice.setNewPushContent(); } } /*DiscoverItems dn = leafNode.discoverItems(); Iterator<Item> it =dn.getItems(); while(it.hasNext()){ Item item = it.next(); String xml = item.toXML(); Log.i(LOGTAG,TAG+xml); }*/ //stopReconnectionThread(); /* VCard vCard = new VCard(); vCard.setFirstName("kir"); vCard.setLastName("max"); vCard.setEmailHome("foo@fee.bar"); vCard.setJabberId("jabber@id.org"); vCard.setOrganization("Jetbrains, s.r.o"); vCard.setNickName("KIR"); vCard.setField("TITLE", "Mr"); vCard.setAddressFieldHome("STREET", "Some street"); vCard.setAddressFieldWork("CTRY", "US"); vCard.setPhoneWork("FAX", "3443233"); try { vCard.save(connection); } catch (XMPPException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } */