title: FTPClient.storeFile() uploads slowly and then doesn't work
body: <p>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 <code>storeFile</code> method in <code>FTPClient</code>, 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 <em>NullPointerException</em> and aborts the activity. </p>
  
  <p>(Also a fourth problem that <code>NetworkInfo.getActiveNetworkInfo()</code> 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.)</p>
  
  <p>Here's my code:
  [<code>Reuse.logIt</code> is a method I use to print to logcat, and <code>printToUI</code> to <code>setText</code> 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.]</p>
  
  <pre><code>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);
          }                   
      }
  
  }
  </code></pre>
  
  <p>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.)</p>
  
  <pre><code>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
  </code></pre>