目前我正在使用新的Smack 4.1,它提供对android的全面支持。发送和接收消息没问题,工作正常。但现在,我被困在发送和接收文件。例如:
public void sendFile(String fileName,String to){
if(transferManager==null) {
transferManager = FileTransferManager.getInstanceFor(mConnection);
}
OutgoingFileTransfer transfer = transferManager.createOutgoingFileTransfer(to);
try {
transfer.sendFile(new File(fileName), "This is a Test!");
} catch (SmackException e) {
e.printStackTrace();
}
}
public void setReceiveFileListener(){
if(transferManager==null) {
transferManager = FileTransferManager.getInstanceFor(mConnection);
}
transferManager.addFileTransferListener(new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer transfer = request.accept();
try {
File file = new File(Environment.getExternalStorageDirectory() + File.separator +"TEST"+File.separator+ "new.txt");
transfer.recieveFile(file);
} catch (SmackException | IOException e) {
e.printStackTrace();
}
}
});
}
在这种情况下,我只发送一个文本文件,并希望将其作为新文本文件保存在SD卡中作为“new.txt”。问题不在于文件本身,文件存在。此外,接收者ID是正确的,就像“user@host.com/Smack”。这是我可以成功发送正常消息的接收器。
错误503 - 服务不可用
这个错误反映我在发送文件后直接从smack获得并且似乎文件没有被传输,因为接收器监听器什么都没有显示(我发送了两个日志,发送和接收),但是肯定会注册监听器。 但我完全相信,文件传输由服务器支持,它在他们的网站www.coderollers.com上声明。我在SO和Smack开发者社区都读过很多关于这里的问题。没有任何帮助,所以我的问题是:
我的正常端口是5222,可以正常发送消息。我希望有人能够让它发挥作用并引导我走向正确的方向....感谢您的帮助!
对于所有感兴趣的人:Devendra Singhs的回答是正确的,我自己也有一点注意事项。似乎重要的是,使用哪种资源。从移动设备到移动设备,您必须使用“mobile”。 Wether“Smack”或任何其他资源标识符都适用于此处。因此,正确初始化OutgoingFileTransfer
非常重要:
OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer
(XmppStringUtils.completeJidFrom(USER, SERV, "mobile"));//important resource "mobile"
答案 0 :(得分:5)
我经过深入研究后得到了它。
FileTransferManager ftm1 = FileTransferManager.getInstanceFor(connection);
FileTransferManager ftm2 = FileTransferManager.getInstanceFor(connection2);
ftm2.addFileTransferListener(new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer ift = request.accept();
try {
InputStream is = ift.recieveFile();
ByteArrayOutputStream os = new ByteArrayOutputStream();
int nRead;
byte[] buf = new byte[1024];
while ((nRead = is.read(buf, 0, buf.length)) != -1) {
os.write(buf, 0, nRead);
}
os.flush();
dataReceived = os.toByteArray();
} catch (SmackException | IOException | XMPPErrorException e) {
e.printStackTrace();
}
if (Arrays.equals(dataToSend, dataReceived)) {
System.out.println("Received data matches send data. \\o/");
} else {
System.err.println("Recieved data DOES NOT match send data. :(");
}
}
});
OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer(XmppStringUtils.completeJidFrom(USER, SERV, "resourse"));
oft.sendStream(new ByteArrayInputStream(dataToSend), "hello.txt", dataToSend.length, "A greeting");
outerloop: while (!oft.isDone()) {
switch (oft.getStatus()) {
case error:
System.out.println("Filetransfer error: " + oft.getError());
break outerloop;
default:
System.out.println("Filetransfer status: " + oft.getStatus() + ". Progress: " + oft.getProgress());
break;
}
Thread.sleep(1000);
}
connection.disconnect();
connection2.disconnect();
Thread.sleep(1000);
}
一个连接正在发送文件而另一个连接正在接收这是工作代码。
答案 1 :(得分:0)
我有同样的问题,我调查了这一节并以这种方式解决了。
许多人使用“/ Smack ”或“/资源”作为jid中的资源部分,但这可以通过其他方式完成。
资源路径随着用户的每次更改而变化。让我们说我们想要向这个用户发送图像: 的 “USER1 @ MYDOMAIN”强>
你必须在这个jid中添加“/ Resource”或“/ Smack”部分,它会变为: 的 USER1 @ MYDOMAIN /资源强>
但资源路径随着状态而变化,因此您必须遵循每个状态更改来更新资源路径。 最好的方法是让用户出现在名册监听器中,并在presencheChanged()方法中获得最后一个用户资源部分:
Roster roster=getRoster();
roster.addRosterListener(new RosterListener() {
@Override
public void entriesAdded(Collection<Jid> addresses) {
Log.d("entriesAdded", "ug");
context.sendBroadcast(new Intent("ENTRIES_ADDED"));
}
@Override
public void entriesUpdated(Collection<Jid> addresses) {
Log.d("entriesUpdated", "ug");
}
@Override
public void entriesDeleted(Collection<Jid> addresses) {
Log.d("entriesDeleted", "ug");
}
@Override
public void presenceChanged(Presence presence) {
Log.d("presenceChanged", "ug");
//Resource from presence
String resource = presence.getFrom().getResourceOrEmpty().toString();
//Update resource part for user in DB or preferences
//...
}
});
}
资源字符串将是一些生成的字符串,如“6u1613j3kv ”,jid将变为: 的 USER1 @ MYDOMAIN / 6u1613j3kv 强>
这意味着您必须像这样创建传出转移:
EntityFullJid jid = JidCreate.entityFullFrom("user1@mydomain/6u1613j3kv");
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(jid)
在您的情况下,此资源部分是“移动”。只需使用资源部分从名册监听器中的状态进行更改即可。
这就是我在smack和Openfire上解决文件传输问题的方法。
另外,您必须在Openfire服务器中添加以下属性:
xmpp.proxy.enabled - true
xmpp.proxy.externalip - MY_IP_ADDRESS
xmpp.proxy.port -7777
请注意,我使用的是Openfire 4.0.2和Smack 4.2.2。
这也可以通过简单的方式进行配置,只需在
上设置资源即可XMPPTCPConnectionConfiguration.Builder。
像
XMPPTCPConnectionConfiguration.Builder configurationBuilder =
XMPPTCPConnectionConfiguration.builder();
configurationBuilder.setResource("yourResourceName");