2016-09-13 5 views
0

OkHttp3ライブラリを使用してAmazon S3にファイルをアップロードしようとしています。 AsyncTaskを使用してファイルをアップロードできます。現在、通常のProgressDialogを表示しています。しかし、ProgressDialogProgressBarに置き換えたいと思います。このために、私は次のことをやって、何とかそれは動作しません:OkHttp3を使用してAndroidでファイルをアップロード中にProgressBarを表示

1)カスタムResponseBodyProgressListener作成:

private static class ProgressResponseBody extends ResponseBody { 

    private final ResponseBody responseBody; 
    private final ProgressListener progressListener; 
    private BufferedSource bufferedSource; 

    public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) { 
     this.responseBody = responseBody; 
     this.progressListener = progressListener; 
    } 

    @Override 
    public MediaType contentType() { 
     return responseBody.contentType(); 
    } 

    @Override 
    public long contentLength() { 
     return responseBody.contentLength(); 
    } 

    @Override 
    public BufferedSource source() { 
     if (bufferedSource == null) { 
      bufferedSource = Okio.buffer(source(responseBody.source())); 
     } 
     return bufferedSource; 
    } 

    private Source source(Source source) { 
     return new ForwardingSource(source) { 
      long totalBytesRead = 0L; 

      @Override 
      public long read(Buffer sink, long byteCount) throws IOException { 
       long bytesRead = super.read(sink, byteCount); 
       // read() returns the number of bytes read, or -1 if this source is exhausted. 
       totalBytesRead += bytesRead != -1 ? bytesRead : 0; 
       progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1); 
       return bytesRead; 
      } 
     }; 
    } 
} 

interface ProgressListener { 
    void update(long bytesRead, long contentLength, boolean done); 
} 

2)をアップロードするための使用AsyncTask内ProgressListenerインタフェースの実装しますファイル:

final ProgressListener progressListener = new ProgressListener() { 
        @Override 
        public void update(long bytesRead, long contentLength, boolean done) { 
         Log.d(AppGlobal.TAG, " " + bytesRead); 
         Log.d(AppGlobal.TAG, " " + contentLength); 
         Log.d(AppGlobal.TAG, " " + done); 
         Log.d(AppGlobal.TAG, (100 * bytesRead)/contentLength + " % done "); 
         Log.d(AppGlobal.TAG, " " + "-------------------------"); 
        } 
       }; 

3)OkHttpクライアントを作成して、ネットワークインターセプタを使用して、手順2で作成しprogressListener渡し:

Request request = new Request.Builder() 
         .header("Proxy-Authorization", "Basic " +  Base64.encodeToString(data, Base64.NO_WRAP)) 
         .addHeader("Content-Type", "application/octet-stream") 
         .addHeader("Connection", "Keep-Alive") 
         .url(url) 
         .put(RequestBody.create(MediaType.parse("application/octet-stream"), file)) 
         .build(); 

OkHttpClient client = new OkHttpClient.Builder() 
         .connectTimeout(1000, TimeUnit.SECONDS) 
         .writeTimeout(1000, TimeUnit.SECONDS) 
         .readTimeout(3000, TimeUnit.SECONDS) 
         .proxy(proxy) 
         .proxyAuthenticator(proxyAuthenticator) 
         .addNetworkInterceptor(new Interceptor() { 
          @Override public okhttp3.Response intercept(Chain chain) throws IOException { 
           okhttp3.Response originalResponse = chain.proceed(chain.request()); 
           return originalResponse.newBuilder() 
             .body(new ProgressResponseBody(originalResponse.body(), progressListener)) 
             .build(); 
          } 
         }) 
         .build(); 

okhttp3.Response response = client.newCall(request).execute(); 

しかし、progressListenerのupdate()関数で使用されるLog.d()ステートメントは決して実行されません。 これらのLogステートメントを印刷すると、それに応じて進捗バーを更新できます。誰かが親切に私を助けられますか?ここで

はAsyncTaskの「doInBackground」の方法で使用される完全なコードです:

@Override 
protected Void doInBackground(File... inputs) { 
try { 
    file = inputs[0]; 
    Date expiration = new Date(); 
    long milliSeconds = expiration.getTime(); 
    milliSeconds += 1000 * 60 * 60; // Add 1 hour. 
    expiration.setTime(milliSeconds); 


    GeneratePresignedUrlRequest generatePresignedUrlRequest = 
      new GeneratePresignedUrlRequest(Constants.BUCKET_NAME, AppGlobal.deviceId + "/" + file.getName()); 
    generatePresignedUrlRequest.setMethod(HttpMethod.PUT); 

    generatePresignedUrlRequest.setContentType("application/octet-stream"); 

    generatePresignedUrlRequest.setExpiration(expiration); 

    final URL url = Util.getS3Client(UploadActivity.this).generatePresignedUrl(generatePresignedUrlRequest); 

    Log.d("DXXXXXX", " URL -> " + url); 

    String domain = AppGlobal.getDomain(UploadActivity.this); 
    int port = Integer.valueOf(AppGlobal.getPort(UploadActivity.this)); 
    final String signature = AppGlobal.getSignature(UploadActivity.this); 


    Proxy proxy = new Proxy(Proxy.Type.HTTP, 
      InetSocketAddress.createUnresolved(domain, port));//the proxy server(Can be your laptop ip or company proxy) 

    try { 

     String headerVal = String.format("%s:%s", "vzServices", signature); 
     final byte[] data = headerVal.getBytes("UTF-8"); 

     okhttp3.Authenticator proxyAuthenticator = new okhttp3.Authenticator() { 
      @Override 
      public Request authenticate(Route route, okhttp3.Response response) throws IOException { 

       String credential = Credentials.basic("vzServices", signature); 
       return response.request().newBuilder().header("Proxy-Authorization", credential).build(); 
      } 
     }; 


     final ProgressListener progressListener = new ProgressListener() { 
      @Override 
      public void update(long bytesRead, long contentLength, boolean done) { 
       Log.d(AppGlobal.TAG, " " + bytesRead); 
       Log.d(AppGlobal.TAG, " " + contentLength); 
       Log.d(AppGlobal.TAG, " " + done); 
       Log.d(AppGlobal.TAG, (100 * bytesRead)/contentLength + " % done "); 
       Log.d(AppGlobal.TAG, " " + "-------------------------"); 
      } 
     }; 


     Request request = new Request.Builder() 
       .header("Proxy-Authorization", "Basic " + Base64.encodeToString(data, Base64.NO_WRAP)) 
       .addHeader("Content-Type", "application/octet-stream") 
       .addHeader("Connection", "Keep-Alive") 
       .url(url) 
       .put(RequestBody.create(MediaType.parse("application/octet-stream"), file)) 
       .build(); 

     OkHttpClient client = new OkHttpClient.Builder() 
       .connectTimeout(1000, TimeUnit.SECONDS) 
       .writeTimeout(1000, TimeUnit.SECONDS) 
       .readTimeout(3000, TimeUnit.SECONDS) 
       .proxy(proxy) 
       .proxyAuthenticator(proxyAuthenticator) 
       .addNetworkInterceptor(new Interceptor() { 
        @Override public okhttp3.Response intercept(Chain chain) throws IOException { 
         okhttp3.Response originalResponse = chain.proceed(chain.request()); 
         return originalResponse.newBuilder() 
           .body(new ProgressResponseBody(originalResponse.body(), progressListener)) 
           .build(); 
        } 
       }) 
       .build(); 

     okhttp3.Response response = client.newCall(request).execute(); 

     responseCode = response.code(); 
     Log.d("Response code : ", " " + response.code()); 
     Log.d("DXXXXXX", " URL 1 -> " + url); 
     success = true; 
     buffer = null; 

    } catch (Exception ex) { 
     // Handle the error 
     Log.d(TAG, "Error: " + ex.getLocalizedMessage()); 
     ex.printStackTrace(); 
    } 


} catch (Exception e) { 

    e.printStackTrace(); 
} 
return null; 
} 

答えて

0

あなただけokhttp3処理を呼び出す前に、最初にプログレスバーを有効にする必要があります。それに応答してエラーが発生したら、それを却下する必要があります。ここで はスニペットです(私はokhttp知らないが、私はボレー何回も使用しました。この例では、あなたは私が何を意味するかを理解できるように十分に単純に維持した。)

sendJsonRequest(){ 

//enable progress bar here 
enableProgressBar();   
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, URL, null, 

new Response.Listener<JSONObject>() { 
@Override 
public void onResponse(JSONObject response) { 
    // dismiss it 
    hideProgressDialog(); 
    System.out.println(response); 
} 
}, 
new Response.ErrorListener() { 
@Override 
public void onErrorResponse(VolleyError error) { 
    // dismiss it and/or handle errors 
    hideProgressDialog(); 
    // ... 
} 
}); 
queue.add(jsObjRequest); 

} 
+0

なぜあなたは、このようなストレートボレーの溶液を得ませんでした。 –

関連する問題