Uploading a file to FTP with Android

At Integrum, we ran in to a situation where we had to upload a file from the Android file system to an FTP server. We found that documentation on the matter was rather sparse so I decided to post about our solution.

We ended up using the Apache commons-net-ftp library that can be found here: http://www.docjar.com/jar_detail/commons-net-ftp-2.0.jar.html

After adding that jar to the build path, the implementation was pretty straightforward:

import org.apache.commons.net.ftp.FTPClient;

FTPClient ftpClient = new FTPClient();

try {
    ftpClient.connect(InetAddress.getByName(SERVER));
    ftpClient.login(USERNAME, PASSWORD);
    ftpClient.changeWorkingDirectory(PATH);

    if (ftpClient.getReplyString().contains("250")) {
        ftpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
        BufferedInputStream buffIn = null;
        buffIn = new BufferedInputStream(new FileInputStream(FULL_PATH_TO_LOCAL_FILE));
        ftpClient.enterLocalPassiveMode();
        ProgressInputStream progressInput = new ProgressInputStream(buffIn, progressHandler);

        boolean result = ftpClient.storeFile(localAsset.getFileName(), progressInput);
        buffIn.close();
        ftpClient.logout();
        ftpClient.disconnect();
    }

} catch (SocketException e) {
    Log.e(SorensonApplication.TAG, e.getStackTrace().toString());
} catch (UnknownHostException e) {
    Log.e(SorensonApplication.TAG, e.getStackTrace().toString());
} catch (IOException e) {
    Log.e(SorensonApplication.TAG, e.getStackTrace().toString());
}

The ProgressInputStream is a custom version of InputStream that takes an instance of android.os.Handler in constructer. the overridden read method sends an update to the Handler after every 10KB transfered (Thanks to Steven Schlansker on Stackoverflow). The following excerpt contains the general idea of how to pass information back to the UI thread.

package com.royvandewater.utils;

import java.io.IOException;
import java.io.InputStream;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class ProgressInputStream extends InputStream {

    /* Key to retrieve progress value from message bundle passed to handler */
    public static final String PROGRESS_UPDATE = "progress_update";

    private static final int TEN_KILOBYTES = 1024 * 10;

    private InputStream inputStream;
    private Handler handler;

    private long progress;
    private long lastUpdate;

    private boolean closed;

    public ProgressInputStream(InputStream inputStream, Handler handler) {
        this.inputStream = inputStream;
        this.handler = handler;

        this.progress = 0;
        this.lastUpdate = 0;

        this.closed = false;
    }

    @Override
        public int read() throws IOException {
            int count = inputStream.read();
            return incrementCounterAndUpdateDisplay(count);
        }

    @Override
        public int read(byte[] b, int off, int len) throws IOException {
            int count = inputStream.read(b, off, len);
            return incrementCounterAndUpdateDisplay(count);
        }

    @Override
        public void close() throws IOException {
            super.close();
            if (closed)
                throw new IOException("already closed");
            closed = true;
        }

    private int incrementCounterAndUpdateDisplay(int count) {
        if (count > 0)
            progress += count;
        lastUpdate = maybeUpdateDisplay(progress, lastUpdate);
        return count;
    }

    private long maybeUpdateDisplay(long progress, long lastUpdate) {
        if (progress - lastUpdate > TEN_KILOBYTES) {
            lastUpdate = progress;
            sendLong(PROGRESS_UPDATE, progress);
        }
        return lastUpdate;
    }

    public void sendLong(String key, long value) {
        Bundle data = new Bundle();
        data.putLong(key, value);

        Message message = Message.obtain();
        message.setData(data);
        handler.sendMessage(message);
    }
}

21 thoughts on “Uploading a file to FTP with Android

  1. Hi Roy,

    First of all congratulate for the web page, is very useful :) . I was wondering if you would help with some problem with android.
    I’m trying to develop a FTP application that makes some directories in a concrete FTP Server.
    I’m working with Eclipse SDK and I am using “org.apache.commons.net.ftp.FTPClient” library.
    I’ve tried the code using normal Java proyect and it works perfectly. the problem comes when I make an Android proyect. I’ll attach to code for a better understading.
    I’d be glad if you can help me.

    Iker

    ——————————————————————-

    import org.apache.commons.net.ftp.FTPClient;
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;

    public class AndroidMuLogger extends Activity
    {

    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button startApplication = (Button) findViewById(R.id.startApplication);

    startApplication.setOnClickListener(new View.OnClickListener()
    {
    public void onClick(View view)
    {

    try
    {
    FTPClient ftpClient = new FTPClient();
    ftpClient.connect(“ftp.whatever.com”);
    ftpClient.login(“user”, “password”);
    ftpClient.changeWorkingDirectory(“/public_html/FOLDERS”);
    ftpClient.mkd(“FOLDER1″);
    ftpClient.logout();
    ftpClient.disconnect();
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }

    }
    });
    }
    }
    ——————————————————————

  2. Great tutorial, this is just what I was looking for. But I can’t get it working.

    In actual workable example, how do you iniate progressHandler and localAsset? I have tried this:

    Handler progressHandler = new Handler();

    In android manifest I have set:

    Do I need to add more permissions?

    How about adding fully working project files to this post?

  3. I have the same comment as dappa has asked.. I was exited to see a client /server code because i was searching for a long for this ftp code. But I cant get it working. Could you provide the source project as such.

  4. dappa,

    I’m not really sure either, but i added the following few lines of code

    import android.os.Handler;

    Handler progressHandler = new Handler();

    and in AndroidManifest.xml i added

    i hope this help. it’s working for me…

    just for extra info: my emulator didn’t work, until i tested in my HTC Android…

  5. Why use BufferedInputStream ?
    and not progressInput = new ProgressInputStream(new FileInputStream(FULL_PATH_TO_LOCAL_FILE), progressHandler);

  6. I liked this tutorial.
    But this code not working properly :(

    ProgressInputStream progressInput = new ProgressInputStream(buffIn, new Handler());
    i inserted “new Handler”.
    we need to write anything else here

    Let me know

    Thanks in advance

    Chandu

  7. I found your tutorial quiet helpful, its working fine with me, but there is only one issue that I need a help for, i.e I am uploading the video files of 1-2 secs to a server machine ftp location. But the files are not getting uploaded there in a proper manner whereas some are missed during the upload, can you probably help me out with this state of my android app??

  8. Won’t even connect tried on 2 different servers. This is all the code I’m running (with the try-catch) and it crashes.

    FTPClient ftpClient = new FTPClient();
    ftpClient.connect(InetAddress.getByName(“ftp.hopscotch.web44.net”));

  9. @Phil
    But now I’m getting a socket exception. Why post code if it doesn’t work? At this point it seems like more code would need to be rewritten then what’s already there. Thanks for wasting my time.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>