溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

在 Android 的 IM 應(yīng)用中使用 asmack 庫實現(xiàn)用戶頭像的傳輸(基于VCard協(xié)議)

發(fā)布時間:2020-06-24 08:30:58 來源:網(wǎng)絡(luò) 閱讀:3897 作者:安靜的瘋子 欄目:移動開發(fā)

根據(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">
 <N>
     <FAMILY/>
     <GIVEN/>
     <MIDDLE/>
 </N>
 <ORG>
     <ORGNAME/>
     <ORGUNIT/>
 </ORG>
 <FN/>
 <URL/>
 <TITLE/>
 <NICKNAME/>

<PHOTO><TYPE>p_w_picpath/jpeg</TYPE><BINVAL>/9j/4AAQSkZJRgABAQEAYABgAAD......YlFFFM4T//2Q==</BINVAL></PHOTO>

 <EMAIL>
     <HOME/>
     <INTERNET/>
     <PREF/>
     <USERID/>
 </EMAIL>
 <TEL><PAGER/><WORK/><NUMBER/>
 </TEL>
 <TEL><CELL/><WORK/><NUMBER/>
 </TEL>
 <TEL><VOICE/><WORK/><NUMBER/>
 </TEL>
 <TEL><FAX/><WORK/><NUMBER/>
 </TEL>
 <TEL><PAGER/><HOME/><NUMBER/>
 </TEL>
 <TEL><CELL/><HOME/><NUMBER/>
 </TEL>
 <TEL><VOICE/><HOME/><NUMBER/>
 </TEL>
 <TEL><FAX/><HOME/><NUMBER/>
 </TEL>
 <ADR><WORK/><PCODE/>
 <REGION/>
 <STREET/>
 <CTRY/>
 <LOCALITY/>
 </ADR>
 <ADR><HOME/><PCODE/>
 <REGION/>
 <STREET/>
 <CTRY/>
 <LOCALITY/>
 </ADR>
 </vCard>

    + 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è)置用戶blueVCard中的頭像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è)置成功了):

在 Android 的 IM 應(yīng)用中使用 asmack 庫實現(xiàn)用戶頭像的傳輸(基于VCard協(xié)議)

d)通過spark登錄成功后,可以看到頭像已經(jīng)更新如下:

   在 Android 的 IM 應(yīng)用中使用 asmack 庫實現(xiàn)用戶頭像的傳輸(基于VCard協(xié)議)

2,查看用戶blueVCard信息

a)首先確認(rèn)ProviderManager已經(jīng)加入vcard-temp,同上;

b)采用異步任務(wù)來獲取用戶blueVCard信息中的昵稱

    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);

        }


向AI問一下細(xì)節(jié)

免責(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)容。

AI