2012-01-06 45 views
4

我有一個可用的android系統,但是我希望能夠跟蹤上傳的字節數,所以我可以在上傳過程中更新進度條。這可能與Android?現在,我正在使用org.apache.common.net.ftp,我使用的代碼如下。另外,我在AsyncTask中運行這個。在android中跟蹤FTP上傳數據?

package com.dronnoc.ftp.complex; 

import java.io.BufferedInputStream; 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.SocketException; 

import org.apache.commons.net.ftp.FTPClient; 
import org.apache.commons.net.io.CopyStreamEvent; 
import org.apache.commons.net.io.CopyStreamListener; 
import org.apache.commons.net.io.Util; 

import android.app.Activity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Window; 

public class Main extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 


     setContentView(R.layout.main); 

     String text = "BIGFILE"; //Big file here 

     InputStream data = new ByteArrayInputStream(text.getBytes()); 

     new ComplexFTPTransfer().execute(data); 
    } 

    private class ComplexFTPTransfer extends AsyncTask<InputStream, Long[], Void> 
    { 
     private FTPClient ftp = null; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

      try { 
       ftp = new FTPClient(); 
       ftp.connect("hostname"); 
      } catch (SocketException e) { 
       this.cancel(true); 
      } catch (IOException e) { 
       this.cancel(true); 
      } 

      Main.this.setProgressBarIndeterminateVisibility(true); 

     } 


     @Override 
     protected Void doInBackground(InputStream... params) { 
      if(!this.isCancelled()) 
      { 
       try 
       { 
        if(ftp.login("user", "pass")) 
        { 
         ftp.enterLocalPassiveMode(); 

         InputStream item = params[0]; 

         int streamSize = 0; 
         while(item.read() != -1) 
         { 
          streamSize++; 
         } 

         InputStream is = new BufferedInputStream(params[0], streamSize); 
         OutputStream os = ftp.storeFileStream("/test.txt"); 

         Util.copyStream(is, os, streamSize, streamSize, new CopyStreamListener() { 

          @Override 
          public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) { 
           publishProgress(new Long[] {totalBytesTransferred, streamSize}); 
          } 

          @Override 
          public void bytesTransferred(CopyStreamEvent event) { 

          } 
         }); 
         ftp.completePendingCommand(); 
        } 
        ftp.logout(); 
        ftp.disconnect(); 

       } 
       catch (IOException e) { 

       } 
       catch (Exception e) { 

       } 
      } 
      return null; 
     } 


     @Override 
     protected void onProgressUpdate(Long[]... values) { 
      super.onProgressUpdate(values); 
      Log.d("UPDATE", values[0] + " of " + values[1] + " copied."); 
      //TODO Put code here 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      // TODO Auto-generated method stub 
      super.onPostExecute(result); 
      Main.this.setProgressBarIndeterminateVisibility(false); 
     } 
    } 
} 

我想知道的是,如果我可以運行一個進度條,更新每隔几上傳字節? 乾杯

+0

同樣的事情的問題與我我不能能夠在上傳時顯示進度,因爲'FTPClient'不要誤解我的完整上載狀態+1 – 2012-01-06 05:50:45

+0

沒錯,FTPClient只會在每次上傳後返回信息,但是當您上傳單個文件時,這會成爲問題。 – 2012-01-06 05:51:39

+0

檢查我的答案[這裏](http://stackoverflow.com/a/26624243/4159043)其工作。 – 2014-10-29 07:03:42

回答

2

This問題有一個包含進度回調的InputStream的實現。在文件上傳過程中,使用該InputStream並從該回調調用publishProgress進行增量更新。

2

下載該.jar文件

httpmime-4.1.1.jarcommons-net.jar

 try { 

      FTPClient ftpClient = new FTPClient(); 

      ftpClient.connect(InetAddress 
        .getByName(Your host Url)); 
      ftpClient.login(loginName, password); 
      System.out.println("status :: " + ftpClient.getStatus()); 

      ftpClient.changeWorkingDirectory(your directory name); 

      ftpClient.setFileType(FTP.IMAGE_FILE_TYPE); 
         //Your File path set here 
         File file = new File("/sdcard/my pictures/image.png"); 
      BufferedInputStream buffIn = new BufferedInputStream(
        new FileInputStream(myImageFile)); 
      ftpClient.enterLocalPassiveMode(); 
      ProgressInputStream progressInput = new ProgressInputStream(
        buffIn); 

      boolean result = ftpClient.storeFile(UPLOADFILENAME + ".png", 
        progressInput); 

      System.out.println("result is :: " + result); 
      buffIn.close(); 
      ftpClient.logout(); 
      ftpClient.disconnect(); 

     } catch (Exception e) { 
      e.printStackTrace(); 

     } 

// ProgressInputStream

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 * 40; 

    private InputStream inputStream; 
    //private Handler handler; 

    private long progress; 
    private long lastUpdate; 

    private boolean closed; 

    public ProgressInputStream(InputStream inputStream) { 
     this.inputStream = inputStream; 

     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); 
    } 
} 
+0

我使用過這個,當涉及到count變量時,它只返回任何理論爲什麼? – 2012-01-08 00:23:52

+0

@BlackWraith我認爲你輸入流可能是null plz首先檢查它。 – 2012-01-09 08:13:45

1

這可以通過使用安全FTP廠庫來完成。

您只需實現com.jscape.inet.ftp.FtpListener接口的實例,使用類註冊實例並重載進度(FtpProgressEvent事件)方法以捕獲進度信息。

的JavaDoc:Overview (secure FTP Factory API)

下載:Java FTP, Java FTPS and Java SFTP Components

+0

這聽起來很有希望,但有沒有我可以使用的免費版本?我不想在單個應用程序中使用一次性使用600美元。 – 2012-01-14 09:49:22