45

短いバージョンの-org.apache...MultipartEntityは非推奨であり、そのアップグレードであるMultipartEntityBuilderは、オンライン フォーラムであまり紹介されていないようです。それを修正しましょう。私の(Android)アプリがファイルをアップロードするときに進行状況バーを表示できるように、コールバックを登録するにはどうすればよいですか?

長いバージョン-これは、「欠落している汚れの単純な例」ですMultipartEntityBuilder:

public static void postFile(String fileName) throws Exception {
    // Based on: https://stackoverflow.com/questions/2017414/post-multipart-request-with-android-sdk

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(SERVER + "uploadFile");
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
    builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    builder.addPart("file", new FileBody(new File(fileName)));
    builder.addTextBody("userName", userName);
    builder.addTextBody("password", password);
    builder.addTextBody("macAddress", macAddress);
    post.setEntity(builder.build());
    HttpResponse response = client.execute(post);
    HttpEntity entity = response.getEntity();

    // response.getStatusLine();  // CONSIDER  Detect server complaints

    entity.consumeContent();
    client.getConnectionManager().shutdown(); 

}  // FIXME  Hook up a progress bar!

それを修正する必要がありますFIXME。(追加の利点は、中断可能なアップロードです。)しかし(間違っているかどうかを修正してください)、すべてのオンライン例は不十分なようです。

たとえば、これhttp://pastebin.com/M0uNZ6SBは、ファイルを「バイナリ/オクテットストリーム」としてアップロードします。「マルチパート/フォームデータ」ではありません。実際のフィールドが必要です。

この例のJava を使用したファイルのアップロード (プログレス バー付き)*Entityは、またはをオーバーライドする方法を示しています*Stream。それで、アップロードの進行状況を測定するオーバーライドされたエンティティMultipartEntityBuilderに伝えることができるでしょうか?.create()

したがって、何かをオーバーライドして、組み込みストリームを 1000 バイトごとにシグナルを送信するカウント ストリームに置き換えたい場合は、その部分を拡張して、そのand/orFileBodyをオーバーライドすることができます。getInputStreamwriteTo

しかし、私が試してみるとclass ProgressiveFileBody extends FileBody {...}、悪名高いjava.lang.NoClassDefFoundError.

それで、私が自分の.jarファイルを調べて、行方不明の Def を探している間に、誰かが私の数学をチェックして、私が見落としていたより簡単な修正を指摘してくれませんか?

4

3 に答える 3

6

その解決策を提供してくれたフィリップに十分に感謝することはできません。プログレスバーのサポートを追加するための最終的な調整は次のとおりです。私はそれを AsyncTask 内で実行しました - 以下の進行状況では、AsyncTask で実行されているクラスの AsyncTask.publishProgress() を呼び出す AsyncTask のメソッドに進行状況をポストバックできます。プログレスバーは正確には滑らかではありませんが、少なくとも動きます。プリアンブルの後に 4MB のイメージファイルをアップロードする Samsung S4 では、4K のチャンクが移動していました。

     class ProgressiveOutputStream extends ProxyOutputStream {
            long totalSent;
            public ProgressiveOutputStream(OutputStream proxy) {
                   super(proxy);
                   totalSent = 0;
            }

            public void write(byte[] bts, int st, int end) throws IOException {

            // FIXME  Put your progress bar stuff here!
            // end is the amount being sent this time
            // st is always zero and end=bts.length()

                 totalSent += end;
                 progress.publish((int) ((totalSent / (float) totalSize) * 100));
                 out.write(bts, st, end);
            }
于 2014-01-17T07:16:42.093 に答える
2

まず第一に、元の質問/回答に感謝します。HttpPost は非推奨になったため、この記事からの追加入力を使用して少し作り直して、そのマイクロ ライブラリを作成しました: https://github.com/licryle/HTTPPoster

全体を ASync タスクにラップします。MultipartEntityBuilder と HttpURLConnection を使用し、コールバックをリッスンします。

使用するには:

  1. ダウンロード & 解凍
  2. build.gradle モジュール ファイルで、依存関係を追加します。
dependencies 
{    
     compile project(':libs:HTTPPoster') 
}
  1. HttpListenerコールバックをリッスンできるように、インターフェイスを実装するクラスが必要です。には 4 つのコールバックがありますHTTPListener

    • onStartTransfer
    • onProgress
    • onFailure
    • onResponse
  2. ASyncTask を構成して開始します。簡単な使い方は次のとおりです。

HashMap<String, String> mArgs = new HashMap<>();
mArgs.put("lat", "40.712784");
mArgs.put("lon", "-74.005941");

ArrayList<File> aFileList = getMyImageFiles();

HttpConfiguration mConf = new HttpConfiguration(
    "http://example.org/HttpPostEndPoint",
    mArgs,
    aFileList,
    this, // If this class implements HttpListener
    null,  // Boundary for Entities - Optional
    15000  // Timeout in ms for the connection operation
    10000, // Timeout in ms for the reading operation
);

new HttpPoster().execute(mConf);

それが役立つことを願っています:) また、改善を提案してください!ごく最近のもので、必要に応じて拡張しています。

乾杯

于 2015-11-09T01:18:19.673 に答える