2011-08-03 19 views
14

私はorg.apache.http.client.HttpClientを介してアンドロイドにファイルをアップロードしており、進捗バーを実装する必要があります。進行状況を把握することは可能ですか?androidのファイルアップロードプログレスバーを実装する方法

HttpPost httppost = new HttpPost("some path"); 
HttpClient httpclient = new DefaultHttpClient(); 
try { 
File file = new File("file path"); 
InputStream in = new BufferedInputStream(new FileInputStream(file)); 
byte[] bArray = new byte[(int) file.length()]; 
in.read(bArray); 
String entity = Base64.encodeToString(bArray, Base64.DEFAULT); 
httppost.setEntity(new StringEntity(entity)); 
HttpResponse response = httpclient.execute(httppost); 
} 

そうでない場合は、別の方法を示してください。ありがとう

+2

この記事は、あなたが探しているものかもしれません:[Java FileUpload with progress](http://stackoverflow.com/questions/254719/file-upload-with-java-with-progress-bar)。 –

答えて

22

あなたはこれを処理できるAsyncTaskを作成し、onProgressUpdateメソッドをオーバーライドします。

ここでは、HttpURLConnectionを使用して別のアプリでテストしたものを削除しました。いくつかの小さな冗長性があるかもしれませんし、私はHttpURLConnectionが一般的に悩まされるかもしれないと思っていますが、これはうまくいくはずです。使用しているアクティビティクラス(この例ではTheActivity)にこのクラスを使用するには、new FileUploadTask().execute()を呼び出してください。もちろん、アプリのニーズに合わせて調整する必要があるかもしれません。

private class FileUploadTask extends AsyncTask<Object, Integer, Void> { 

    private ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(TheActivity.this); 
     dialog.setMessage("Uploading..."); 
     dialog.setIndeterminate(false); 
     dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     dialog.setProgress(0); 
     dialog.show(); 
    } 

    @Override 
    protected Void doInBackground(Object... arg0) { 
     try { 
      File file = new File("file path"); 
      FileInputStream fileInputStream = new FileInputStream(file); 
      byte[] bytes = new byte[(int) file.length()]; 
      fileInputStream.read(bytes); 
      fileInputStream.close(); 

      URL url = new URL("some path"); 
      HttpURLConnection connection = 
        (HttpURLConnection) url.openConnection(); 
      OutputStream outputStream = connection.getOutputStream(); 

      int bufferLength = 1024; 
      for (int i = 0; i < bytes.length; i += bufferLength) { 
       int progress = (int)((i/(float) bytes.length) * 100); 
       publishProgress(progress); 
       if (bytes.length - i >= bufferLength) { 
        outputStream.write(bytes, i, bufferLength); 
       } else { 
        outputStream.write(bytes, i, bytes.length - i); 
       } 
      } 
      publishProgress(100); 

      outputStream.close(); 
      outputStream.flush(); 

      InputStream inputStream = connection.getInputStream(); 
      // read the response 
      inputStream.close(); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... progress) { 
     dialog.setProgress(progress[0]); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     try { 
      dialog.dismiss(); 
     } catch(Exception e) { 
     } 

    } 

} 
+1

これは効率的ではありません.100までスムーズに進んでから、実際にファイルが転送されたときにダイアログが消えてから100%で止まってしまいます。上記のコードには何か不足していますか? – Hunt

+8

実際のアップロードは、outputStreamをフラッシュすると開始されます。 進行状況が偽の進捗です – Basbous

+3

OutputStreamを取得する前に 'connection.setDoOutput(true)'を忘れないでください! – Nolesh

3

私はHttpURLConnectionのは、単にトリックを行うとは思わない@Basbousが指摘したようにoutputStream.flush()が呼び出されるまで、実際のデータはbufferredされます。アンドロイドissue 3164によると、それは現在、フロイド後のプラットフォーム(アンドロイド2.2、SDKバージョン8)で修正されています。バッファ動作を回避するには、java.net.HttpURLConnection.setFixedLengthStreamingModeを使用する必要があります。

関連する問題