您好,登錄后才能下訂單哦!
根據(jù) XMPP 的 XEP 標(biāo)準(zhǔn)協(xié)議規(guī)范,實現(xiàn) avatar 頭像傳輸與存儲的功能主要有三種實現(xiàn)方式,分別對應(yīng)于協(xié)議規(guī)范:
+ 【XEP-0153】vCard-BasedAvatars http://xmpp.org/extensions/xep-0153.html
+ 【XEP-0084】UserAvatar http://xmpp.org/extensions/xep-0084.html
+ 【XEP-0008】IQ-BasedAvatars http://xmpp.org/extensions/xep-0008.html
其中
+ XEP-0153是通過將 avatar 頭像存儲在 vcard 的 XML 報文中實現(xiàn)的,這個也是 openfire 和 spark 中支持的方式;
在 openfire 中的 vcard 的實現(xiàn)都在 org.jivesoftware.openfire.vcard 包中,其中:
- 用戶的 vcard 的存儲實現(xiàn)在類 DefaultVCardProvider 中處理了 vcard 的查詢,刪除,更新,新增等 DB 操作;
- 在VCardManager 中實現(xiàn)對 vcard 的緩存與管理(包括新增,刪除,更新,以及查詢);
這種實現(xiàn)方式比較直接,在服務(wù)端就是將用戶的 vcard(XML格式)信息一起存儲在表(ofVcard)中,示例:
<vCard xmlns="vcard-temp"> |
+ XEP-0008的 IQ-Based Avatars 實現(xiàn)方式現(xiàn)在已不被推薦,用官方協(xié)議來說:
WARNING: Consideration of this document has been Deferred by the XMPP Standards Foundation. Implementation of the protocol described herein is not recommended |
+ XEP-0084 User Avatar 是通過基于 pubsub 協(xié)議的基礎(chǔ)上實現(xiàn)用戶 頭像 的發(fā)布(publish) 與 其他用戶的訂閱(subscribe);這也是 beem 的實現(xiàn)方式(beem 中也提供了直接通過 url 的方式下載頭像);
在 User Avatar 的協(xié)議中定義了兩個 pubsub 節(jié)點,分別為:
- metadata 節(jié)點:主要包括 avatar 的狀態(tài)信息;
- data 節(jié)點:就是 avatar 的數(shù)據(jù);
該協(xié)議也指出可以通過 HTTP 協(xié)議方式訪問 avatar 的存儲;
按照官方協(xié)議說法,該協(xié)議的實現(xiàn)方式可能要替代其他兩種實現(xiàn)方式:
It is intended that this specification will supersede both IQ-Based Avatars [6]and vCard-Based Avatars [7] once the PEP subset of XMPP publish-subscribe isimplemented and deployed widely enough.
針對 user avatar 方式的實現(xiàn),針對 publisher 與 subscriber 至少需要完成如下功能:
- Publishing avatar data
- Updating metadata about the current avatar
- Disabling avatars
- Discovering avatar availability
- Receiving notification of avatar changes
- Retrieving avatar data via pubsub
- Retrieving avatar data via HTTP
上面只是對實現(xiàn)avatar相關(guān)XEP協(xié)議做一個初步的了解,我這里的實例仍然“偷懶”采用了VCard方式實現(xiàn)。
協(xié)議參考: http://xmpp.org/extensions/xep-0054.html
Smack 中的 VCard API 參考: http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/
1,設(shè)置用戶blue的VCard中的頭像avatar信息:
a)首先確認(rèn)ProviderManager已經(jīng)加入vcard-temp,如下代碼:
ProviderManager pm = ProviderManager.getInstance(); // Private Data Storage pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider()); // Roster Exchange pm.addExtensionProvider("x", "jabber:x:roster", new RosterExchangeProvider()); // Message Events pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider()); // 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()); |
b)設(shè)置用戶選擇的頭像(其中還附帶演示了設(shè)置用戶blue的其他信息,如FirstName,LastName,以及NickName),如下示例代碼:
public class SetVCardTask extends AsyncTask<Uri, Integer, Long> { @Override protected Long doInBackground(Uri... params) { if (params.length < 1) { return Long.valueOf(-1); } Uri uriFile = params[0]; // 需要傳輸?shù)念^像文件 ByteArrayOutputStream baos = new ByteArrayOutputStream(); FileInputStream fis; try { String[] proj = { MediaStore.Images.Media.DATA }; Cursor actualp_w_picpathcursor = managedQuery(uriFile,proj,null,null,null); int actual_p_w_picpath_column_index = actualp_w_picpathcursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); actualp_w_picpathcursor.moveToFirst(); String filePath = actualp_w_picpathcursor.getString(actual_p_w_picpath_column_index); fis = new FileInputStream(new File(filePath)); byte[] buf = new byte[1024]; int n; while (-1 != (n = fis.read(buf))) { baos.write(buf, 0, n); } } catch (Exception e) { e.printStackTrace(); } byte[] bbytes = baos.toByteArray(); // 設(shè)置和更新用戶信息 VCard vCard = new VCard(); vCard.setFirstName("Steven"); vCard.setLastName("Hu"); vCard.setNickName("安靜的瘋子"); vCard.setAvatar(bbytes); try { vCard.save(MainHelloIM.getInstance().getConnection()); } catch (XMPPException e) { e.printStackTrace(); } return Long.valueOf(0); } } |
c)最終在服務(wù)端的數(shù)據(jù)庫中可以看到如下數(shù)據(jù)(其中可以看到用戶昵稱也都設(shè)置成功了):
d)通過spark登錄成功后,可以看到頭像已經(jīng)更新如下:
2,查看用戶blue的VCard信息
a)首先確認(rèn)ProviderManager已經(jīng)加入vcard-temp,同上;
b)采用異步任務(wù)來獲取用戶blue的VCard信息中的昵稱
public class GetVCardTask extends AsyncTask<String, Integer, Long> { @Override protected Long doInBackground(String... params) { if (params.length < 1) { return Long.valueOf(-1); } // 獲取用戶 params[0] 的 vcard 信息 try { // load(Connection connection, String user) vcard.load(MainHelloIM.getInstance().getConnection(), params[0]); Log.d(TAG, "nickname: " + vcard.getNickName()); } catch (XMPPException e) { e.printStackTrace(); return Long.valueOf(-2); } return Long.valueOf(0); } |
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。