FTPClient.storeFile() uploads slowly and then doesn't work

Displaced Hoser picture Displaced Hoser · Mar 29, 2013 · Viewed 9.1k times · Source

Android n00b trying to figure out file server upload. I'm having a lot of trouble trying to upload a file to my FTP server in Android using the storeFile method in FTPClient, testing on a Galaxy Nexus. Two problems. First, it runs very, VERY slowly - like a minute or more for a file of a few bytes before the code moves on (so that my display often goes to sleep before it finishes running). Second, no file arrives on the server when it's done. But the code does continue running and I don't get any explicit error messages telling me something's wrong, as far as I can tell. But third, AFTER all that (and logout), it gives me a NullPointerException and aborts the activity.

(Also a fourth problem that NetworkInfo.getActiveNetworkInfo() always seems to return CONNECTED even when I'm not connected, but that seems to be unrelated and I want to focus on the bigger problems.)

Here's my code: [Reuse.logIt is a method I use to print to logcat, and printToUI to setText on the display. As you can probably tell, I'm trying to give myself a lot of signposts to figure out what's going on.]

public void uploadFile(String filename, File theFile)
{

      Reuse.logIt(TAG, "UploadFile did run."); // test that at least    
      FTPClient theClient = new FTPClient();

      // It's probably insecure to do it this way, but first I just want to make it work.
      final String theSite = [the name of my site];
      String username = [my username];
      String password = [my password];


        // get network status
        Context theContext = getApplicationContext();
        ConnectivityManager cMgr = (ConnectivityManager)theContext.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo netInfo = cMgr.getActiveNetworkInfo();

        String beginStatus = netInfo.getState().toString();
        // always says CONNECTED whether we're connected or not. 
        String networkStatus = "Network status = "+beginStatus;

        Reuse.logIt(TAG, networkStatus); 

        // pass the network status where it can be displayed in a different window's text. 
        Brouillon instance = (Brouillon) theContext;
        instance.setDataResult(networkStatus);

        if (beginStatus == "CONNECTED")
        // If we don't have a network connection, don't upload the file.
        {

            try
            {               
                theClient.connect(theSite); 

                // When login succeeds, the login method returns true.
                boolean login = theClient.login(username, password); 

                if (login)
                {
                    // success!
                    Reuse.logIt(TAG, "Logged in successfully to "+theSite+"!");
                    printToUI("ftp_connect", "Logged in successfully to "+theSite+"!");

                    Reuse.logIt(TAG, "The code does continue after logging in.");


                    // Now upload the file.
                    String ftpPath = "/brouillon/";
                    String filenameOnFTP = ftpPath+filename;
                    Reuse.logIt(TAG, "It defined the variables.");


                    FileInputStream fis = new FileInputStream(theFile);
                    Reuse.logIt(TAG, "It created the FileInputStream too.");

                    theClient.storeFile(filenameOnFTP, fis);

                    Reuse.logIt(TAG, "We created a file called "+filenameOnFTP+".");
                    printToUI("upload","We created a file called "+filenameOnFTP+".");

                }
                else
                {
                    Reuse.logIt(TAG, "Could not connect to "+theSite+".");
                    printToUI("ftp_connect","Could not connect to "+theSite+".");
                }

                boolean logout = theClient.logout();
                if (logout) 
                {
                    Reuse.logIt(TAG, "Logged out successfully.");
                    printToUI("loggedout","Logged out successfully.");
                }
                else 
                {
                    Reuse.logIt(TAG, "Logout failed!");
                    printToUI("loggedout","Logout failed!");
                }

            }
            catch(IOException e)
            {
                e.printStackTrace(); 
                Reuse.logIt(TAG, "Got error message "+e.toString()+".");

            }
        }
        else
        {
            // For testing purposes, abort the program if not connected. Can change that later.
            Reuse.logIt(TAG, "beginStatus was not CONNECTED!");
            System.exit(0);
        }                   
    }

}

And here's my logcat. (Set on Error mode. If giving a more verbose mode would help, I'm happy to do that, but I'm leaving it out at first because it would make this post really long.)

03-29 13:08:13.400: E/SyncStatus(8764): Sync button pushed.
03-29 13:08:13.400: E/SyncStatus(8764): File created and closed.
03-29 13:08:13.400: E/SyncStatus(8764): UploadFile did run.
03-29 13:08:13.431: E/SyncStatus(8764): Network status = CONNECTED
03-29 13:08:14.556: E/SyncStatus(8764): Logged in successfully to [site name]!
03-29 13:08:14.556: E/SyncStatus(8764): The code does continue after logging in.
03-29 13:08:14.556: E/SyncStatus(8764): It defined the variables.
03-29 13:08:14.556: E/SyncStatus(8764): It created the FileInputStream too.
03-29 13:10:32.283: E/wpa_supplicant(452): android_priv_cmd: failed to issue private commands
03-29 13:11:28.603: E/SyncStatus(8764): We created a file called /brouillon/filename.txt.
03-29 13:11:28.705: E/SyncStatus(8764): Logged out successfully.
03-29 13:11:28.713: E/AndroidRuntime(8764): FATAL EXCEPTION: main
03-29 13:11:28.713: E/AndroidRuntime(8764): java.lang.NullPointerException
03-29 13:11:28.713: E/AndroidRuntime(8764):     at com.loveofallwisdom.brouillon.SyncStatus$2.run(SyncStatus.java:174)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at android.os.Handler.handleCallback(Handler.java:725)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at android.os.Looper.loop(Looper.java:137)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at android.app.ActivityThread.main(ActivityThread.java:5041)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at java.lang.reflect.Method.invokeNative(Native Method)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at java.lang.reflect.Method.invoke(Method.java:511)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-29 13:11:28.713: E/AndroidRuntime(8764):     at dalvik.system.NativeStart.main(Native Method)
03-29 13:11:38.931: E/wpa_supplicant(452): android_priv_cmd: failed to issue private commands

Answer

fenix picture fenix · Mar 29, 2013

please try it to do in this way:

public static String uploadOrder(String fileName)
{

    String m;

    FTPClient con = null;

    m = "Conn failed";

    try
    {
       con = new FTPClient();

       con.connect("xxx.xxx.210.176");

       //username and password for ftp server
       if (con.login("ftpxxx@xxxxx", "pass"))
       {
          con.enterLocalPassiveMode();//passive mode - IMPORTANT
          con.setFileType(FTP.ASCII_FILE_TYPE);//only for txt file ACII mode, for rest binary mode
          String data = Environment.getExternalStorageDirectory().getPath() +"/"+ fileName; //data location 
          FileInputStream in = new FileInputStream(data);
          File f = new File(data);          

          con.changeWorkingDirectory("xxxxxx");//        
          if(con.changeWorkingDirectory("Orders"))//
          {
             Log.i("FTP","Got into directory");
          }
          if(!con.changeWorkingDirectory(MainPage.fb_id))//
          {

              in.close();
              con.logout();
              con.disconnect();
              return m;
          }


          if(con.storeFile(fileName, in))
          {               
              m = "Upload success!";
          }
          if(!f.exists()) m = "File not exists.";
          in.close();
          //logging out
          con.logout();
          con.disconnect();
       }
       else 
       {                     
           m = "Unsuccessful";
       }
    }
    catch (Exception e)
    {
          m = e.getMessage();
    }
    return m;
}