I am creating a sync service which will copy files to ftp folder selected by user. When i run the service, it connects with ftp and check whether file at android local storage is available at ftp or not and if not, it uploads. Below is my code.
FTPClient ftpClient = new FTPClient();
ftpClient.setPassive(true);
if (!ftpClient.isConnected()) {
ftpClient.connect(server, port);
}else {
Log.i(TAG,"FTP already connected");
}
if (!ftpClient.isAuthenticated()) {
ftpClient.login(username, password);
}else {
Log.i(TAG,"FTP already Logged In");
}
ftpClient.changeDirectory(rfolderpath);
String[] files = ftpClient.listNames();
if (Arrays.asList(files).contains(filename)) {
Log.i(TAG, filename + " Already Found in FTP, Skipping");
} else {
Log.i(TAG, "Sending Go Ahead For Upload");
File file = new File(filepath);
Log.i(TAG, "Uploading File: " + filename);
ftpClient.upload(file);
ftpClient.logout();
ftpClient.disconnect(true);
}
The code works fine for first 8 files and then i start getting exception of too many connections (8) from this IP and my sync terminates.
Here is Error text:
it.sauronsoftware.ftp4j.FTPException [code=421, message= Too many connections (8) from this IP]
Can someone help me how to handle this scenario.
I changed the logic of uploading files. Now created one ftp connection under AsyncTaskLoader and with that upload all files w/o error.
Related
f.connect("ftp.drivehq.com",21);
if(f.login("XXXX", "XXX"))
{
f.enterLocalPassiveMode();
f.setFileType(FTP.BINARY_FILE_TYPE);
FileInputStream in = new FileInputStream(URL);
result = f.storeFile(newfile, in);
in.close();
f.logout();
f.disconnect();
}
It upload fine but not in particular path i also try as ftp://ftp.drivehq.com/myfolder
but it gives error in android unknown host exception like I need to upload file in particular folder So thanks in advance help me
Hi Please use the following code. it worked for me i have checked it.
SimpleFTP ftp = new SimpleFTP();
try
{
// Connect to an FTP server on port 21.
ftp.connect("host", 21, "username", "password");
// Set binary mode.
ftp.bin();
// Change to a new working directory on the FTP server.
ftp.cwd("/httpdocs/yourdestinationfolderinftp");
// Upload some files.
ftp.stor(new File("/mnt/sdcard/ftp.jpg"));
// Quit from the FTP server.
ftp.disconnect();
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
I created an Android project on 2.3.3 and tried it on mobile 2.3.3, everything works OK. It didn't work on mobile 4, so I re-built for Android 4, but I have the same problem.
This is the code:
public void FTP_Download(){
String server = "192.168.1.135";
int port = 21;
String user = "pc1";
String pass = "1551";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
Toast.makeText(getBaseContext(), "download starting.",Toast.LENGTH_LONG).show();
// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "i.xml";
File downloadFile1 = new File("sdcard/i.xml");
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
Toast.makeText(getBaseContext(), "File #1 has been downloaded successfully.",Toast.LENGTH_LONG).show();
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Note:
I use commons-net-3.1 to connect.
In android version 2.3 above you can not start internet connection from main UI thread. Instead you should use AsyncTask. I assumed you are not using AsyncTask. If you are, then post the code and log cat also. Some examples of other operations that ICS and HoneyComb won't allow you to perform on the UI thread are:( from link posted in comment below ) -
Opening a Socket connection (i.e. new Socket()).
HTTP requests (i.e. HTTPClient and HTTPUrlConnection).
Attempting to connect to a remote MySQL database.
Downloading a file (i.e. Downloader.downloadFile()).
You should not use the main UI Thread to start a network connection or read/write data from it as #phazorRise explained it. But I strongly disagree with using an AsyncTask to perform your download. AsyncTask have been designed for short living operations and downloading a file doesn't belong to that category.
The most relevant way to achieve your goal, if your files are big (and I assume it depends on users, so we can say they are big) is to use a service to download the files.
I invite you to have a look at RoboSpice, it will give your app robustness for networking and it's really the most interesting library for network requests on Android.
Here is an inforgraphics to get familiarized with alternatives and understand why using a service is better than any other technology.
When I use "internet conections" programming for andoid 4, I do an Async Task as follows:
You can put this Class code into the same file as principal file to intercatue with global variables or functions.
public class MyAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String url = urls[0]
try {
//Connection request code, in your case ftp
} catch (Exception e) {
//Catch code
}
}
#Override
protected void onPostExecute(String result) {
//Code to de After the connection is done
}
}
Then, in the Activity I call the Asyn Task
String url = "http://...";
new MyAsyncTask().execute(url);
Edit
Here it's explained how to use Async Task, with an example
http://developer.android.com/reference/android/os/AsyncTask.html
I added this code, and all thing OK
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Note: I taked the code from #user1169115 comment in another post.
This isn't the best soluation, but I don't know why asynctask isn't work, so I don't have another choice.
In my application I want to upload video using ftp. I included apache.commons.net library in my application. When I am running the code it shows 04-28 14:56:05.229: ERROR/dalvikvm(739): Could not find class 'org.apache.commons.net.ftp.FTPClient', referenced from method net.jeema.hwdvideoshare.NewVideoActivity$loadVideo.doInBackground.
How to solve this problem? I am using the below code:
protected Void doInBackground(Void... arg0) {
String hostName = "ftp.host.net";
String username = "test";
String password = "test";
String location = selectedPath;
InputStream in = null;
try {
FTPClient ftp = new FTPClient();
ftp.connect(hostName);
ftp.login(username, password);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory("/uploads");
int reply = ftp.getReplyCode();
System.out.println("Received Reply from FTP Connection:" + reply);
if (FTPReply.isPositiveCompletion(reply)) {
System.out.println("Connected Success");
}
File f1 = new File(location);
in = new FileInputStream(f1);
ftp.storeFile(fname, in);
System.out.println("SUCCESS");
ftp.logout();
ftp.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
When you link de lib do you have to reference it, and mark as a usable one.
maybe you forgot one of the two steps?
Open your app’s Properties dialog, navigate to “Java Build Path”->”Libraries” and add the reference.
Navigate to “Java Build Path”->”Order and Export” and select to export the two jars.
I first want to get a list of files stored in an FTP directory and then get the name of last created file using timestamp. And I'm getting an alert box: Activity is not responding. After checking logcat entry, I notice that the code never reach line :
Log.e("FTP", "number of filenames: " + count);
But I get to Log.e("FTP", "Connexion successful "); So connexion to the server seems ok.
It Seems like something going wrong out there. Can someone help me deal with it. Or show me a simple way to get the last created file from an the FTP server director?
FTPClient ftpClient = new FTPClient();
try
{
ftpClient.connect(InetAddress.getByName(Fonctions.address), Integer.parseInt(Fonctions.port));
if (ftpClient.login(Fonctions.login, Fonctions.pass))
{
Log.e("FTP", "Connexion successful ");
String workDir = ftpClient.printWorkingDirectory();
//Log.e("FTP", "workdir:" + workDir);
int count = ftpClient.listNames().length;
Log.e("FTP", "number of filenames: " + count);
FTPFile [] dossier = new FTPFile[count];
FTPFile back = new FTPFile();
dossier = ftpClient.listDirectories("Sarelo_FTP");
back = dossier[0];
Log.e("FTP", "Avant boucle " + back);
int buf = 0;
for (int i=0;i<(dossier.length) - 1;i++)
{
for (int j=1;j<dossier.length;j++)
{
buf = back.getTimestamp().compareTo(dossier[j].getTimestamp());
if (buf == -1)
back = dossier[j];
}
}
Log.e("FTP", "fichier final le plus récent: " + back.getName());
}
else{
Log.e("Restore FTP", "Error while connecting to FTP server");
}
}
catch(IOException e)
{
String title = "Error connecting to FTP server";
String msg = "Please check your parameters and connexion info: login, password,port number";
f.alert(c, title, msg).show();
Log.e("Restore FTP", "Error while connecting to FTP server", e);
}
P.S: I can't get the list of files in the directory so, I don't know if my code to retrieve the last created file is working. Any help on that would also be appreciated.
[Edit] This is my AsyncTask to retrieve the list of files in the directory. But it's still not working. I'm not getting Application Not Responding anymore, but It not seems to do anything else. Execution get stuck at the same point (can't reach Log.e("FTP", "number of filenames: " + count); )
class getFilesFromFtp extends AsyncTask
{
#Override
protected String doInBackground(Object... params)
{
int count = 0;
try
{
Log.e("FTP", "avant names: " + count);
count = ftpClient.listNames().length;
Log.e("FTP", "names: " + count);
handler.sendMessage(handler.obtainMessage());
}
catch (IOException e) {
Log.e("FTP", "Error getting number of files ", e);
}
return null;
}
}
Thanks for help.
You must not execute long running code on UI thread. Thia blocks UI redraw and event handling. It also produces ANR.
You should run it in the background thread, preferably via 'AsyncTask'.
First problem solved. I just needed to activate FTP data connection passive mode like that:
ftpClient.enterLocalPassiveMode();
before line int count = ftpClient.listNames().length;.
Hope this will help other people. Thanks to #Peter Knego driving me to AsynkTask. I learned something new. :)
I am unable to recive the file, which I am transfering from SPARK client.
I am using ASMACK jar Library so it's not possible to get into the library.
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");
}
// new ServiceDiscoveryManager(connection);
FileTransferNegotiator.setServiceEnabled(connection, false);
FileTransferManager manager = new FileTransferManager(connection);
manager.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(FileTransferRequest request) {
Log.d("", "allows file...");
if (request != null) {
// Accept it
IncomingFileTransfer transfer = request.accept();
try {
// String pathsd = Environment.getExternalStorageDirectory().toString();
String path = "/sdcard/"+ request.getFileName();
transfer.recieveFile(new File(path));
// transfer.recieveFile(new
// File(request.getFileName()));
System.out.println("File " + request.getFileName() + "Received Successfully");
// Log.d("", "rece: " + request.getFileName());
// Log.d("", "path: " + request.getFileName());
// InputStream input = transfer.recieveFile();
} catch (XMPPException ex) {
Log.d("", "er: " + ex);
}
} else {
Log.d("", "reject file...");
request.reject();
}
}
});
Don't know what version of Smack your asmack is based on, but there is a known issue with file transfer in Smack, which both asmack and Spark are based on.
Beems asmack build process is well documented and also the sources are open for everyone.
Your code looks right, but why do you set this
FileTransferNegotiator.setServiceEnabled(connection, false);
to false?
File transfer in XMPP is a rather complex topic. There are various methods (at least 4), to get a file from one resource to another. As you provided no further details I can only give you general device on how to debug this:
Enable connection debug in smack, which will print out and log all XMPP packets that go in and out. Trace the XMPP stanzas that relate to the file transfer and make sure they behave as specified in the XEPs. This may provides a hint about whats going wrong.