I have a problem on handling the file transfer from an "Android chat" to an other client (like Pidgin): the Pidgin client receives the transfer request, but my application cannot start transferring the file.
I must say that I've read all stackoverflows questions, some http://community.igniterealtime.org/ threads, but all that didn't solve my problems.
In order to test, i'm using the jabber.org server on port 5222, and I'm using the Beem-Asmack library v7 (in some clients you must also specify the proxy: is this necessary??). The code for file transfer is the following:
public boolean sendFile(final String jid, final String path, String description) {
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(this.xmpp);
/*if (sdm==null) {
sdm = new ServiceDiscoveryManager(this.xmpp);*/
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("http://jabber.org/protocol/disco#item");
sdm.addFeature("jabber:iq:privacy");
//}
Log.d("sending file", "maganer");
FileTransferNegotiator.setServiceEnabled(this.xmpp, true);
FileTransferManager manage = new FileTransferManager(this.xmpp);
Log.d("sending file", "set true");
OutgoingFileTransfer.setResponseTimeout(10000);
OutgoingFileTransfer oft = manage.createOutgoingFileTransfer(this.myRoster.getPresence(jid).getFrom());
try {
Log.d("sending file", "try to send... " + path);
oft.sendFile(new File(path), description);
Log.d("sending file", "Accepted");
while (!oft.isDone()) {
Log.d("status", oft.getStatus().toString());
Log.d("percent", new Long(oft.getBytesSent()).toString());
if (oft.getStatus() == FileTransfer.Status.error) {
Log.e("percent", "Error " + new Long(oft.getBytesSent()).toString() + " " + oft.getError() + " " + oft.getException());
oft.cancel();
return false;
}
//Thread.sleep(1000);
}
} catch (Throwable e) {
e.printStackTrace();
Log.e("sendFile", path);
return false;
}
return true;
}
I'm also doing the following procedure at the creation of my Remote Service
private void startup() {
ProviderManager pm = ProviderManager.getInstance();
// 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());
//
pm.addExtensionProvider("x","jabber:x:data", new DataFormProvider());
// 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());
// 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());
}
Now I'll describe my error: from the logging, i receive -1 as "percent" and "Negotiating Stream" as "status". I don't know where I'm wrong and how to start the trasfer. Thanks for any advice or suggestions.
EDIT (2) Now I've partially solved my problem by adding
FileTransferNegotiator.IBB_ONLY = true;
before initializing the FileTransferManager and rearranging the ServiceDiscoveryManager initialization as follows:
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(this.xmpp);
if (sdm==null)
sdm = new ServiceDiscoveryManager(this.xmpp);
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("http://jabber.org/protocol/disco#item");
sdm.addFeature("jabber:iq:privacy");
I've also added the following Configuration at startup:
SmackConfiguration.setPacketReplyTimeout(15000);
By the way, now I reach a progress value of the same amount of the original file, but the file is not closed on the receiver side. Consequently, the timeout is raised and the transfer is aborted. How can I communicate the finalization of the file? It seems that I transfer the whole file, even if the other client (Pidgin) doesn't handle it. Thanks again in advance.