Androidpn里的Xmpp的理解
转自?http://handsomeliuyang.iteye.com/blog/1300195
?
XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。用xmpp来实现android的push功能,感觉有点大材小用了,xmpp本身是一种即时通信协议。
? xmpp是一种用于即时通信的协议,使用过程有点类似于我们使用QQ的过程,其使用过程分为三步:
? 1. 连接服务器,就好像打开QQ软件,看代码:
- if(!mXmppManager.isConnected())?{??
- ????ConnectionConfiguration?config?=?new?ConnectionConfiguration(mHost,?mPort);??
- ????config.setSecurityMode(SecurityMode.required);??
- ????config.setSASLAuthenticationEnabled(false);??
- ????config.setCompressionEnabled(false);??
- ??????
- ????XMPPConnection?connection?=?new?XMPPConnection(config);??
- ????mXmppManager.setConnection(connection);??
- ????try?{??
- ????????connection.connect();??
- ????????Log.i(LOGTAG,?"XMPP?connected?successfully");??
- ?????????
- ?
- ?
- ??
- ????????ProviderManager.getInstance().addIQProvider("notification",??
- ????????????????"androidpn:iq:notification",??
- ????????????????new?NotificationIQProvider());??
- ??????????
- ????}?catch?(XMPPException?e)?{??
- ????????Log.d(LOGTAG,?"the?connection?is?error?...?");??
- ????}??
- ????mXmppManager.runTask();??
- }?else?{??
- ????Log.i(LOGTAG,?"XMPP?connected?already");??
- ????mXmppManager.runTask();??
- }??
?
这一步主要是连接服务器,还有设置一些连接的参数,还有设置连接的解析器。
? 2. 如果没有用户,注册新的帐号和密码
?
- if(!mXmppManager.isRegistered()){??
- ????final?String?newUsername?=?newRandomUUID();??
- ????final?String?newPassword?=?newRandomUUID();??
- ????Registration?registration?=?new?Registration();??
- ??????
- ????PacketFilter?packetFilter?=?new?AndFilter(new?PacketIDFilter(??
- ????????????registration.getPacketID()),?new?PacketTypeFilter(??
- ????????????IQ.class));??
- ????PacketListener?packetListener?=?new?PacketListener()?{??
- ????????@Override??
- ????????public?void?processPacket(Packet?packet)?{??
- ??????????????
- ????????????if(packet?instanceof?IQ)?{??
- ????????????????IQ?response?=?(IQ)?packet;??
- ????????????????if(response.getType()?==?IQ.Type.ERROR)?{???
- ????????????????????if?(!response.getError().toString().contains(??
- ????????????????????????????"409"))?{??
- ????????????????????????Log.e(LOGTAG,"Unknown?error?while?registering?XMPP?account!?"?+?response.getError().getCondition());??
- ????????????????????}??
- ????????????????}?else?if(response.getType()?==?IQ.Type.RESULT)?{???
- ????????????????????mXmppManager.setUsername(newUsername);??
- ????????????????????mXmppManager.setPassword(newPassword);??
- ??????????????????????
- ????????????????????Editor?editor?=?mSharedPrefs.edit();??
- ????????????????????editor.putString(Contants.XMPP_USERNAME,?newUsername);??
- ????????????????????editor.putString(Contants.XMPP_PASSWORD,?newPassword);??
- ????????????????????editor.commit();??
- ??????????????????????
- ????????????????????mXmppManager.runTask();??
- ????????????????}??
- ????????????}??
- ????????}??
- ????};??
- ??????
- ????mConnection.addPacketListener(packetListener,?packetFilter);??
- ??????
- ????registration.setType(IQ.Type.SET);??
- ????registration.addAttribute("username",?newUsername);??
- ????registration.addAttribute("password",?newPassword);??
- ??????
- ??????
- ????mConnection.sendPacket(registration);??
- ??????
- }?else?{???
- ????mXmppManager.runTask();??
- }??
?
?
?只要连接了服务器了,客户端就可以向服务器端发送消息,发送是以Packet(数据包)来进行发送的,这个类有很多的子类,注册的子类为Registration。
?
?
?
?
?
?
?还有要注意的是,上面的addPacketListener方法不是给所有发送的数据包设置listener,而只是针对这次的注册Packet。
? 3. 用注册的帐号和密码进行登陆(像用QQ号帐进行登陆一样)
- ??
- if(!mXmppManager.isAuthenticated())?{??
- ????try?{??
- ????????mConnection.login(mUsername,?mPassword,?"AndroidpnClient");??
- ??????????
- ????????if(mXmppManager.getConnectionListener()?!=?null)?{??
- ????????????mConnection.addConnectionListener(mXmppManager.getConnectionListener());??
- ????????}??
- ??????????
- ????????PacketFilter?packetFilter?=?new?PacketTypeFilter(NotificationIQ.class);??
- ????????PacketListener?packetListener?=?mXmppManager.getNotificationPacketListener();??
- ????????mConnection.addPacketListener(packetListener,?packetFilter);??
- ??????????
- ????????mXmppManager.runTask();??
- ????}?catch?(XMPPException?e)?{??
- ??????????
- ????????String?INVALID_CREDENTIALS_ERROR_CODE?=?"401";??
- ????????String?errorMessage?=?e.getMessage();??
- ??????????
- ????????if?(errorMessage?!=?null?&&?errorMessage.contains(INVALID_CREDENTIALS_ERROR_CODE))?{??
- ????????????mXmppManager.reregisterAccount();???
- ????????????return;??
- ????????}??
- ????????mXmppManager.startReconnectionThread();??
- ????}?catch?(Exception?e)?{???
- ????????Log.e(LOGTAG,?"LoginTask.run()...?other?error");??
- ????????Log.e(LOGTAG,?"Failed?to?login?to?xmpp?server.?Caused?by:?"?+?e.getMessage());??
- ????????mXmppManager.startReconnectionThread();???
- ????}??
- }?else?{??
- ????mXmppManager.runTask();??
- }??
?
? 这里设置了连接的监听器mConnection.addConnectionListener(),连接过程中有可以连接突然中断,连接出错等等问题,要进行监听。
? 设置服务器推送信息的Listener,接收到信息后,显示给用户。
? 如果出错的原因是401(无效的用户名和密码,则应该进行重新注册,再连接)
?
对于服务器push过来的信息进行处理,是在PacketListener类里面,这个接口里,只要实现一个方法processPacket(Packet packet),从传过来的Packet(数据包)里获取自己需要的数据:
?
- public?void?processPacket(Packet?packet)?{??
- ????if(packet?instanceof?NotificationIQ)?{??
- ????????NotificationIQ?notification?=?(NotificationIQ)?packet;??
- ????????if(notification.getChildElementXML().contains("androidpn:iq:notification"))?{??
- ????????????String?notificationId?=?notification.getId();??
- ????????????String?notificationApiKey?=?notification.getApiKey();??
- ????????????String?notificationTitle?=?notification.getTitle();??
- ????????????String?notificationMessage?=?notification.getMessage();??
- ????????????String?notificationUri?=?notification.getUri();??
- ??
- ????????????Intent?intent?=?new?Intent(Contants.ACTION_SHOW_NOTIFICATION);??
- ????????????intent.putExtra(Contants.NOTIFICATION_ID,?notificationId);??
- ????????????intent.putExtra(Contants.NOTIFICATION_API_KEY,notificationApiKey);??
- ????????????intent.putExtra(Contants.NOTIFICATION_TITLE,notificationTitle);??
- ????????????intent.putExtra(Contants.NOTIFICATION_MESSAGE,?notificationMessage);??
- ????????????intent.putExtra(Contants.NOTIFICATION_URI,?notificationUri);??
- ??
- ????????????mXmppManager.getContext().sendBroadcast(intent);??
- ????????}??
- ????}??
- }??
?