在 Android 应用程序中使用 smack 进行文件传输。

Posted

技术标签:

【中文标题】在 Android 应用程序中使用 smack 进行文件传输。【英文标题】:File transfer using smack in android apps. 【发布时间】:2012-03-20 07:14:13 【问题描述】:

日志中出现此错误。

from='kutbi1@360degree/Smack' to='akash@360degree/Smack' type='error' id='hK1L6-5'>
<si xmlns='http://jabber.org/protocol/si' id='jsi_191216212994140179' mime-type='image/png' profile='http://jabber.org/protocol/si/profile/file-transfer'>
<file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='this_old_house.png' size='12623'>
<desc>You won&apos;t believe this!</desc></file>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x xmlns='jabber:x:data' type='form'><field var='stream-method' type='list-multi'>
 <option><value>http://jabber.org/protocol/bytestreams</value></option>
 <option><value>http://jabber.org/protocol/ibb</value></option>
</field>
 </x>
</feature>
</si>
<error code='503' type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error></iq>

我在这里使用了以下代码

    ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(Main.connection);
    if (sdm == null)
        sdm = new ServiceDiscoveryManager(Main.connection);
    sdm.addFeature("http://jabber.org/protocol/disco#info");
    sdm.addFeature("jabber:iq:privacy");

   FileTransferNegotiator.setServiceEnabled(Main.connection, true);
   FileTransferManager manager = new FileTransferManager(Main.connection);
  OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(id
           + "/Smack");

   Log.i("transfere file", "outgoingfiletransfere is created");
    try
        //OutgoingFileTransfer.setResponseTimeout(60000);
        transfer.sendFile(new File(txt_file.getText().toString()), "You won't believe this!");

        if (transfer.getStatus().equals(Status.cancelled)
                || transfer.getStatus().equals(Status.refused)) 
                Log.d("Cancel", ""+transfer.getError());
                System.out.println("Cancelled!!! " + transfer.getError());
            

        Log.i("transfere file", "sending file");
        Log.d("FTTRY", "m in ft TRY");
        btn_transfer.setText("Browse");
        txt_file.setText("click on browse n Select File");
        send_flag = true;
    catch (Exception e) 
        Log.d("FTCATCH", "m in ft catch");
        btn_transfer.setText("BrowseC");
        send_flag = true;
    

    while(!transfer.isDone()) 
        try
           Thread.sleep(1000);
        catch (Exception e) 
        
          Log.i("transfere file", "sending file status "
                      + transfer.getStatus() + "progress: "
                      + transfer.getProgress());
       if(transfer.getStatus().equals(Status.error)) 
             System.out.println("ERROR!!! " + transfer.getError());
        else 
             System.out.println(transfer.getStatus());
             System.out.println(transfer.getProgress());
             Log.d("PROG", "m in ft progress");
       
      try
       Thread.sleep(1000);
      catch (Exception e) 
    
 

【问题讨论】:

您使用的是哪个版本的 smack? asmack15 我从 5 天开始尝试,但仍然无法通过 smack 传输文件。如果您对此有任何想法,请提供帮助 @Hussain 我用过这个版本的 smack :-asmack-android-7-beem.jar @Akash:试试这个解决方案community.igniterealtime.org/thread/30695 @Hussain 我试过这个链接。但我的问题没有解决...... 【参考方案1】:

我通过执行以下步骤解决了同样的问题。

我在 Eclipse 中为 android-2.2 使用 asmack-2010.05.07-source

转到 asmack 中的 ProviderManager 类。替换以下代码

Enumeration providerEnum = classLoader.getResources(
                        "/META-INF/smack.providers");

有了这个

Enumeration providerEnum = classLoader.getResources(
                        "/data/smack.providers");

在这之后你需要做一个补丁。在创建之前添加以下函数 new XMPPConnection。您可以通过

调用此函数
 configure(ProviderManager.getInstance());

这就是方法。

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

我从以下链接http://code.google.com/p/asmack/issues/detail?id=23得到了解决方案

【讨论】:

我已经尝试过了。但我的问题仍然存在。这不能解决。 如何为我的 android 项目包含 asmack 库。我遇到了很多错误【参考方案2】:

谢谢, 但我解决了我的问题.. 问题是对方用户没有登录。所以我刚刚安装了sparkx clinet表单http://www.igniterealtime.org/downloads/download-landing.jsp?file=spark/spark_2_6_3.exe并使用其他用户登录,就是这样。

以下是完整的工作代码。 你需要在 General.java 中设置你的服务器和端口 我也有固定用户在活动,所以你需要根据你的配置来改变它。

https://sites.google.com/site/fancifulandroid/android-projects/FiletransfarXMPP.rar?attredirects=0&d=1

【讨论】:

以上是关于在 Android 应用程序中使用 smack 进行文件传输。的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 的 SmackInitialization 中无法获得 smack 版本

在 android 上使用 smack 面临问题

如何在 Android 应用中使用 Smack 从 Openfire 服务器恢复两个用户之间的聊天记录

如何在 Android 的 Smack 4.2 中了解 1:1 对话中的打字状态?

找不到提供程序类 SMACK 4.1.1 Android

如何使用 Smack 从 android 客户端获取 openfire 在线注册用户?