I have made a chatting application. I want to add photo/file sharing concept in my application same as WhatsApp. I have made the app using Xmpp/Openfire and current now I am using this function for photo sharing, but it is not all reliable :
public void sendFile(final String path, final String receiver) {
Thread thread = new Thread() {
public void run() {
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(connection);
if (sdm == null)
sdm = new ServiceDiscoveryManager(connection);
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
// Create the file transfer manager
FileTransferManager manager = new FileTransferManager(
connection);
FileTransferNegotiator.setServiceEnabled(connection, true);
// Create the outgoing file transfer
OutgoingFileTransfer transfer = manager
.createOutgoingFileTransfer(receiver + "/Smack");
System.out.println("Receiver of the file is "+receiver+"/smack");
Log.i("transfere file", "outgoingfiletransfer is created");
try {
OutgoingFileTransfer.setResponseTimeout(30000);
transfer.sendFile(new File(path), "Description");
Log.i("transfere file", "sending file");
while (!transfer.isDone()) {
try {
Thread.sleep(1000);
Log.i("transfere file", "sending file status "
+ transfer.getStatus() + "progress: "
+ transfer.getProgress());
if (transfer.getStatus() == Status.error) {
Log.i("transfere file", "Errorrr isss: "
+ transfer.getError());
transfer.cancel();
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("transfere file", "sending file done");
}
};
thread.start();
}
I want to do it same as WhatsApp or any other good means. Please suggest a good solution
Thanks
Related
Thanks for paying attention over the question...
I am making a XMPP chat application with the help of ejabbered and asmack_4.1 library.
I have installed a PSI client for windows to chat with the android device.
I am able to perform text chat between devices.
I am also able to send file from device to PSI client and PSI client to android device.
But the problem is to send files device to device.
I am using below code to send and receive files :
File send :
public void fileTransfer(String filenameWithPath, Bitmap thumbnail, String userId) {
// FileTransferManager manager = new FileTransferManager(connection);
FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
// OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer("usre2#myHost/Smack");
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userId + "/Admin"); // "/Good" depends on server
// OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userId + "/Directors-iMac");
File file = new File(filenameWithPath);
try {
transfer.sendFile(file, "test_file");
} catch (SmackException e) {
e.printStackTrace();
}
while (!transfer.isDone()) {
if (transfer.getStatus().equals(FileTransfer.Status.error)) {
System.out.println("ERROR!!! " + transfer.getError());
} else if (transfer.getStatus().equals(FileTransfer.Status.cancelled)
|| transfer.getStatus().equals(FileTransfer.Status.refused)) {
System.out.println("Cancelled!!! " + transfer.getError());
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (transfer.getStatus().equals(FileTransfer.Status.refused) || transfer.getStatus().equals(FileTransfer.Status.error)
|| transfer.getStatus().equals(FileTransfer.Status.cancelled)) {
System.out.println("refused cancelled error " + transfer.getError());
} else {
System.out.println("Success");
}
}
File Receiving :
public void fileReciever(AbstractXMPPConnection connection) {
//**************************************
// Create the file transfer manager
final FileTransferManager managerListner = FileTransferManager.getInstanceFor(connection);
// FileTransferNegotiator.setServiceEnabled(connection, true);
FileTransferNegotiator negotiator = FileTransferNegotiator.getInstanceFor(connection);
Log.i("File transfere manager", "created");
// Create the listener
managerListner
.addFileTransferListener(new FileTransferListener() {
#Override
public void fileTransferRequest(FileTransferRequest request) {
Log.i("Recieve File", "new file transfere request new file transfere request new file transfere request");
Log.i("file request", "from" + request.getRequestor());
IncomingFileTransfer transfer = request.accept();
Log.i(RECIEVE_FILE_ALERT_DIALOG, "accepted");
try {
transfer.recieveFile(new File("/sdcard/" + request.getFileName()));
while (!transfer.isDone() || (transfer.getProgress() < 1)) {
Log.i(RECIEVE_FILE_ALERT_DIALOG, "still receiving : " + (transfer.getProgress()) + " status " + transfer.getStatus());
if (transfer.getStatus().equals(FileTransfer.Status.error)) {
// Log.i("Error file",
// transfer.getError().getMessage());
Log.i("Recieve File",
"cancelling still receiving : "
+ (transfer.getProgress())
+ " status "
+ transfer.getStatus());
transfer.cancel();
break;
}
}
} /*catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/ catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//**************************************
}
Note : In fileTransfer() method, I am using below line:
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userId + "/Admin"); // "/Good" depends on server
I am able to send files from Android device to PSI desktop application and vice versa but i am not able to transfer files between android devices.
I'm working on file sharing using Asmack and XMPP. I am able to send file but not able to receive file on another device. I did so much of Research and Development, found so many ways tried all of them but haven't got success. Seems I am making any small mistake, tried a lot but haven't got solution for my problem. The code I used for sending file is:
d.findViewById(R.id.btnsendphoto).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!filepath.equals("")) {
configureProviderManager(connection);
FileTransferNegotiator.IBB_ONLY = true;
FileTransferNegotiator.setServiceEnabled(
connection, true);
mFileTransferManager = new FileTransferManager(
connection);
String to = connection.getRoster()
.getPresence("cac6ba9dc9c6ac67#pc")
.getFrom();
final OutgoingFileTransfer transfer = mFileTransferManager
.createOutgoingFileTransfer(to);
File file = new File(filepath);
try {
configureProviderManager(connection);
transfer.sendFile(file, "test_file");
} catch (XMPPException e) {
e.printStackTrace();
}
new AsyncTask<Void, Void, Void>() {
protected void onPreExecute() {
}
#Override
protected Void doInBackground(
Void... params) {
while (!transfer.isDone()) {
if (transfer.getStatus().equals(
"Error")) {
Log.d("file transfer",
"ERROR!!! "
+ transfer
.getError());
} else if (transfer.getStatus()
.equals("Cancelled")
|| transfer.getStatus()
.equals("Refused")) {
Log.d("file transfer",
"Cancelled!!! "
+ transfer
.getError());
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
};
protected void onPostExecute(Void result) {
if (transfer.getStatus().equals(
"Refused")
|| transfer.getStatus().equals(
"Error")
|| transfer.getStatus().equals(
"Cancelled")) {
Log.i("file transfer",
"refused cancelled error "
+ transfer
.getError());
} else {
Log.i("file transfer", "Success: "
+ transfer.getFileName());
messages.add("file sent");
setListAdapter();
}
};
}.execute();
}
d.dismiss();
}
});
I am able to send file. I got this message file sent on sending side, here configureProviderManager is this
and I have tried many ways that I got on Google but I would like to mention one of those here
First is:
public void ReceiveFile() {
System.out.println("in ReceiveFile");
Thread thread = new Thread() {
public void run() {
System.out.println("in Thread");
configureProviderManager(connection);
// Create the file transfer manager
final FileTransferManager managerListner = new FileTransferManager(
connection);
FileTransferNegotiator.setServiceEnabled(connection, true);
Log.i("File transfere manager", "created");
// Create the listener
managerListner
.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(
final FileTransferRequest request) {
Log.i("Recieve File",
"new file transfere request");
Log.i("file request",
"from" + request.getRequestor());
IncomingFileTransfer transfer = request
.accept();
Log.i("Recieve File alert dialog", "accepted");
try {
transfer.recieveFile(new File("/sdcard/"
+ request.getFileName()));
while (!transfer.isDone()
|| (transfer.getProgress() < 1)) {
Thread.sleep(1000);
Log.i("Recieve File alert dialog",
"still receiving : "
+ (transfer
.getProgress())
+ " status "
+ transfer.getStatus());
if (transfer.getStatus().equals(
Status.error)) {
// Log.i("Error file",
// transfer.getError().getMessage());
Log.i("Recieve File alert dialog",
"cancelling still receiving : "
+ (transfer
.getProgress())
+ " status "
+ transfer
.getStatus());
transfer.cancel();
break;
}
}
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
};
thread.start();
}
Debugging this code
I am not even getting this log new file transfer request. Kindly please tell what mistake I am making and how can I correct this.
File albumF = getVideoAlbumDir();
String path = albumF.getAbsolutePath();
// path =/storage/emulated/0/Pictures/.MyImages (Hidden folder)
// fileSelected.fileName()=IMG_20140417_113847.jpg
File localFile = new File(path + "/" + fileSelected.fileName());
Log.v("", "file exist===" + localFile.exists());
if (!localFile.exists()) {
Log.v("", "inside if===");
Log.v("", "Parent Filet===" + localFile.getParentFile());
localFile.getParentFile().mkdirs();
// localFile.createNewFile();
copy(fileSelected, localFile);
} else {
Log.v("", "inside else===");
mCurrentPhotoPath = localFile.getAbsolutePath();
uploadMediaFile();
}
This copy method copies data from dropbox file to my local storage.
private void copy(final Entry fileSelected, final File localFile) {
final ProgressDialog pd = ProgressDialog.show(ChatActivity.this,
"Downloading...", "Please wait...");
new Thread(new Runnable() {
#Override
public void run() {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
DropboxInputStream fd;
try {
fd = mDBApi.getFileStream(fileSelected.path,
localFile.getAbsolutePath());
br = new BufferedInputStream(fd);
bw = new BufferedOutputStream(new FileOutputStream(
localFile));
byte[] buffer = new byte[4096];
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
pd.dismiss();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
android.os.Message msg = new android.os.Message();
msg.arg1 = 100;
if (msg.arg1 >= 100) {
progressHandler.sendMessage(msg);
mCurrentPhotoPath = localFile.getAbsolutePath();
}
} catch (DropboxException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
I am creating file in a folder using localFile.getParentFile().mkdirs();
I got above error when I upload this file to server.
how to fix this?
If you've tried all other options - and problem still persists - then maybe you have a case when the file you want to create matches name of already existing directory.(which might be earlier created my some call to mkdirs() maybe accidentally).
Example:
You want to save file Test\test.pdf but you already have folder Test\Test.pdf\
I am using asmack 18-0.8.9.
below is my sending file method
public void send()
{
configureProviderManager(connection);
FileTransferNegotiator.setServiceEnabled(connection, true);
FileTransferManager manager = new FileTransferManager(connection);
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer("xxxxx#jabber.ccc.de/Smack");
File file = new File("/sdcard/DCIM/Camera/1385869353956.jpg");
try {
Log.d("file sending",file.getAbsolutePath()+" "+file.getName());
configureProviderManager(connection);
transfer.sendFile(file, "test_file");
} catch (XMPPException e) {
e.printStackTrace();
}
while(!transfer.isDone()) {
if(transfer.getStatus().equals(Status.error)) {
System.out.println("ERROR!!! " + transfer.getError());
} else if (transfer.getStatus().equals(Status.cancelled)
|| transfer.getStatus().equals(Status.refused)) {
System.out.println("Cancelled!!! " + transfer.getError());
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(transfer.getStatus().equals(Status.refused))
System.out.println("refused " + transfer.getError());
else if( transfer.getStatus().equals(Status.error))
System.out.println(" error " + transfer.getError());
else if(transfer.getStatus().equals(Status.cancelled))
System.out.println(" cancelled " + transfer.getError());
else
System.out.println("Success");
}
Below is my receiver part
FileTransferManager manager = new FileTransferManager(connection);
manager.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(final FileTransferRequest request) {
new Thread(){
#Override
public void run() {
IncomingFileTransfer transfer = request.accept();
Log.d("receive","file name: "+transfer.getFileName());
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + "/download");
dir.mkdirs();
File file = new File(dir+transfer.getFileName());
try {
transfer.recieveFile(file);
} catch (XMPPException e1) {
// TODO Auto-generated catch block
}
while(!transfer.isDone()) {
try{
Thread.sleep(1000L);
}catch (Exception e) {
Log.d("receive","thread sleep"+ e.getMessage());
}
if(transfer.getStatus().equals(Status.error)) {
Log.d("error","error status"+ transfer.getError() + "");
}
if(transfer.getException() != null) {
transfer.getException().printStackTrace();
}
}
};
}.start();
}
});
I can successfully receive file from other desktop clients like psi, pidgin. When I try to send file from my android app to other desktop client or my own app installed on other phone they do not receive any XMPP message. While when I send file from other desktop client to my android app I can see XMPP message and successfully receive message.
Below is my configureProviderManager method
public void configureProviderManager() {
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
}
I am using following code for file transfer in android application using Smack Api and Oepnfire Server. I am not getting any error but problem is that when I send file , I get Cancelled Status at 198 line. Can anybody help me? .Thanks in advance .
String to = mRecipient.getText().toString();
String text = mSendText.getText().toString();
// Uri uri = Uri.fromFile(new
// File("file:///android_asset/test.txt"));
if (new File("/data/data/" + getPackageName() + "/"
+ "test.txt").exists()) {
Log.d("XMPPClient File Exist", "exist");
}
SmackConfiguration.setPacketReplyTimeout(15000);
ConnectionConfiguration config = new ConnectionConfiguration(
"192.168.1.200", 5222);
// config.setRosterLoadedAtLogin(true);
// config.setSendPresence(true);
// config.setSASLAuthenticationEnabled(false);
config.setReconnectionAllowed(true);
connection = new XMPPConnection(config);
/*
* ConnectionConfiguration connConfig = new
* ConnectionConfiguration("192.168.1.200", 5222, "");
* connConfig.setReconnectionAllowed(true);;
*
* connection = new XMPPConnection(connConfig);
*/
try {
connection.connect();
} catch (XMPPException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
connection.connect();
} catch (XMPPException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// connection.login(userName, password);
ServiceDiscoveryManager servicemanager = ServiceDiscoveryManager
.getInstanceFor(connection);
if (servicemanager == null)
servicemanager = new ServiceDiscoveryManager(connection);
servicemanager
.addFeature("http://jabber.org/protocol/disco#info");
servicemanager.addFeature("jabber:iq:privacy");
// Log.d("XMPPClient Txt File", uri.toString());
try {
// Create the outgoing file transfer
manager = new FileTransferManager(connection);
FileTransferNegotiator.setServiceEnabled(connection, true);
OutgoingFileTransfer transfer = manager
.createOutgoingFileTransfer("test#192.168.1.200/Smack");
// Send the file
// getBaseContext().getAssets().open("Entity");
// OutgoingFileTransfer.setResponseTimeout(30000);
transfer.sendFile(new File("/data/data/" + getPackageName()
+ "/" + "test.txt"), "You won't believe this!");
while (!transfer.isDone()) {
try {
Thread.sleep(1000);
Log.i("transfere file", "sending file status "
+ transfer.getStatus() + "progress: "
+ transfer.getProgress());
if (transfer.getStatus() == org.jivesoftware.smackx.filetransfer.FileTransfer.Status.error) {
transfer.cancel();
Log.e("", transfer.getStatus().toString());
Log.e("", "EEEEEERRRRRRRROOORRRRR");
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.e("aaaaaaaaaaaaaaa", "aaaa" + e);
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Yes, you have to setup FileTransferListener and accept the file
public class MyFileTransferListener implements FileTransferListener {
#Override
public void fileTransferRequest(final FileTransferRequest request) {
Boolean result = false;
IncomingFileTransfer ift = request.accept();
this is an example code, after accepting get the file.. also dont forget to start the listener when connecting to xmpp server