2017-07-03 91 views
0

我應該如何可以顯示每個文件我的Android使用的上傳按鈕上傳進度條,這樣的事情: Uploading Screenshot如何顯示分別對多個上傳上傳進度 - Android電子

我曾嘗試這樣做使用服務和通知,但我想展示在UI本身的進展。

任何代碼示例將有所幫助。

我使用下面的班多上傳:

public class MultipartUtility 
 
{ 
 
    FileUploadListener listener; 
 
    private static final int BUFFER_SIZE = 1024; 
 
    private static final int TIME_OUT = 3 * 60 * 1000; 
 
    private final String boundary; 
 
    private static final String LINE_FEED = "\r\n"; 
 
    private HttpURLConnection httpConn; 
 
    private String charset; 
 
    private OutputStream outputStream; 
 
    private PrintWriter writer; 
 
    public int statusCode; 
 
    public String mURL; 
 

 
    public interface FileUploadListener { 
 
     void onUpdateProgress(int percentage, long kb); 
 
     boolean isCanceled(); 
 
    } 
 

 
    /** 
 
    * This constructor initializes a new HTTP POST request with content type 
 
    * is set to multipart/form-data 
 
    * 
 
    * @param requestURL 
 
    * @param charset 
 
    * @throws IOException 
 
    */ 
 
    public MultipartUtility(Context context, String requestURL, String charset, FileUploadListener listener) 
 
      throws IOException { 
 
     this.charset = charset; 
 
     this.listener = listener; 
 
     mURL = requestURL; 
 
     // creates a unique boundary based on time stamp 
 
     boundary = "" + System.currentTimeMillis() + ""; 
 

 
     URL url = new URL(requestURL); 
 
     httpConn = null; 
 
     if (url.getProtocol().toLowerCase().equals("https")) { 
 
      trustAllHosts(); 
 
      HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); 
 
      https.setHostnameVerifier(new HostnameVerifier() { 
 
       @Override 
 
       public boolean verify(String hostname, SSLSession session) { 
 
        return true; 
 
       } 
 
      }); 
 
      httpConn = https; 
 
     } else { 
 
      httpConn = (HttpURLConnection) url.openConnection(); 
 
     } 
 

 
     // httpConn.setConnectTimeout(TIME_OUT); 
 
     //httpConn.setReadTimeout(TIME_OUT); 
 
     httpConn.setUseCaches(false); 
 
     httpConn.setDoOutput(true); // indicates POST method 
 
     httpConn.setDoInput(true); 
 
     httpConn.setChunkedStreamingMode(BUFFER_SIZE); 
 
     httpConn.setRequestMethod("POST"); 
 
     Storage storage = new Storage(context); 
 
     httpConn.setRequestProperty("x-auth", storage.readString("user_token")); 
 
     httpConn.setRequestProperty("Content-Type", 
 
       "multipart/form-data; boundary=" + boundary); 
 
     httpConn.setRequestProperty("Connection", "Keep-Alive"); 
 
     outputStream = httpConn.getOutputStream(); 
 
     writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), 
 
       true); 
 
    } 
 

 
    private static void trustAllHosts() { 
 
     // Create a trust manager that does not validate certificate chains 
 
     TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { 
 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
 
       return new java.security.cert.X509Certificate[]{}; 
 
      } 
 

 
      public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
 
      } 
 

 
      public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
 
      } 
 
     }}; 
 

 
     // Install the all-trusting trust manager 
 
     try { 
 
      SSLContext sc = SSLContext.getInstance("TLS"); 
 
      sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
 
      HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
 
     } catch (Exception e) { 
 
      e.printStackTrace(); 
 
     } 
 
    } 
 

 

 
    /** 
 
    * Adds a form field to the request 
 
    * 
 
    * @param name field name 
 
    * @param value field value 
 
    */ 
 
    public void addFormField(String name, String value) { 
 
     writer.append("--" + boundary).append(LINE_FEED); 
 
     writer.append("Content-Disposition: form-data; name=\"" + name + "\"") 
 
       .append(LINE_FEED); 
 
     writer.append("Content-Type: text/plain; charset=" + charset).append(
 
       LINE_FEED); 
 
     writer.append(LINE_FEED); 
 
     writer.append(value).append(LINE_FEED); 
 
     writer.flush(); 
 
    } 
 

 
    /** 
 
    * Adds a upload file section to the request 
 
    * 
 
    * @param fieldName name attribute in <input type="file" name="..." /> 
 
    * @param uploadFile a File to be uploaded 
 
    * @throws IOException 
 
    */ 
 
    private long lastProgressUpdateTime = 0; 
 

 
    public void addFilePart(String fieldName, File uploadFile) 
 
      throws IOException { 
 
     String fileName = uploadFile.getName(); 
 
     writer.append("--" + boundary).append(LINE_FEED); 
 
     writer.append(
 
       "Content-Disposition: form-data; name=\"" + fieldName 
 
         + "\"; filename=\"" + fileName + "\"") 
 
       .append(LINE_FEED); 
 
     writer.append(
 
       "Content-Type: " 
 
         + URLConnection.guessContentTypeFromName(fileName)) 
 
       .append(LINE_FEED); 
 
     writer.append("charset=" + charset).append(
 
       LINE_FEED); 
 
     writer.append(LINE_FEED); 
 
     writer.flush(); 
 

 
     outputStream.flush(); 
 
     byte[] buffer = new byte[BUFFER_SIZE]; 
 

 
     try { 
 
      final FileInputStream inputStream = new FileInputStream(uploadFile); 
 
      long totalRead = 0; 
 
      long totalSize = uploadFile.length(); 
 

 
      int read; 
 
      while ((read = inputStream.read(buffer)) > 0) { 
 
       totalRead += read; 
 
       int percentage = (int) ((totalRead/(float) totalSize) * 100); 
 
       outputStream.write(buffer, 0, read); 
 

 
       long now = System.currentTimeMillis(); 
 
       if (lastProgressUpdateTime == 0 || lastProgressUpdateTime < now - 100) { 
 
        lastProgressUpdateTime = now; 
 

 
        Log.e("", totalRead + " " + " " + percentage); 
 

 
        if (listener != null) 
 
         this.listener.onUpdateProgress(percentage, totalRead); 
 
       } 
 
      } 
 
     } catch (Exception e) { 
 
      e.printStackTrace(); 
 
     } finally { 
 
      outputStream.flush(); 
 
     } 
 

 
     writer.append(LINE_FEED); 
 
     writer.flush(); 
 
    } 
 

 

 
    /** 
 
    * Adds a header field to the request. 
 
    * 
 
    * @param name - name of the header field 
 
    * @param value - value of the header field 
 
    */ 
 
    public void addHeaderField(String name, String value) { 
 
     writer.append(name + ": " + value).append(LINE_FEED); 
 
     writer.flush(); 
 
    } 
 

 
    /** 
 
    * Completes the request and receives response from the server. 
 
    * 
 
    * @return a list of Strings as response in case the server returned 
 
    * status OK, otherwise an exception is thrown. 
 
    * @throws IOException 
 
    */ 
 
    public String Execute() throws IOException { 
 
     String responses = ""; 
 

 
     writer.append(LINE_FEED).flush(); 
 
     writer.append("--" + boundary + "--").append(LINE_FEED); 
 
     writer.close(); 
 
     StringBuilder sb = new StringBuilder(); 
 
     try { 
 
      // checks server's status code first 
 
      statusCode = httpConn.getResponseCode(); 
 
      //responses = ; 
 

 
      sb.append("" + Helpers.convertStreamToString(httpConn.getInputStream()) + "\n"); 
 

 
      if (statusCode == HttpURLConnection.HTTP_OK) { 
 
       httpConn.disconnect(); 
 
      } 
 
      responses = sb.toString(); 
 
      return responses; 
 
     } catch (Exception e) { 
 
      // TODO Auto-generated catch block 
 
      e.printStackTrace(); 
 
      sb = new StringBuilder(); 
 

 
      sb.append("" + Helpers.convertStreamToString(httpConn.getErrorStream()) + "\n"); 
 

 
      responses = sb.toString(); 
 
     } 
 
     return responses; 
 
    } 
 
}

回答

0

爲此創建一個單獨的設計,併爲每個下載的文件創建與鍵值的HashMap條目的條目。例如,對於file1,應該有一個鍵,值應該是其更新的進度。並根據文件上傳進度(當進度更新的回調接收時)對該密鑰進行更新。並根據密鑰從該哈希映射更新進度條。因爲哈希映射將始終具有更新值。希望有所幫助。 在我的一個項目中,我實現了同樣的目標。我分享,現在

創建下載服務

public class DownloadService extends IntentService { 

public DownloadService() { 
    super("DownloadService"); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    String rhymeName = intent.getStringExtra(Constants.RHYME_NAME); 
    String URL = intent.getStringExtra(Constants.URL); 
    downloadRhyme(rhymeName, URL); 
} 

private void sendMyBroadCast(long currentProgress, long totalVideoSize, String rhymeName) { 
    Intent intentUpdate = new Intent(); 
    intentUpdate.setAction(Constants.ACTION_MYUPDATE); 
    intentUpdate.addCategory(Intent.CATEGORY_DEFAULT); 
    intentUpdate.putExtra(Constants.UPDATED_VALUES, currentProgress); 
    intentUpdate.putExtra(Constants.TOTAL_VIDEO_SIZE, totalVideoSize); 
    intentUpdate.putExtra(Constants.RHYME_NAME, rhymeName); 
    sendBroadcast(intentUpdate); 
} 

private void registerMyTaskCompletedListener(ITaskCompletedListener taskCompletedListener, boolean successful, String rhymeName) { 
    if (successful) 
     taskCompletedListener.taskCompleted(rhymeName); 
    else 
     taskCompletedListener.taskFailed(rhymeName); 
} 


private final void downloadRhyme(String rhymeName, String URL) { 

    boolean successful = false; 
    URL downloadURL = null; 
    HttpURLConnection httpURLConnection = null; 
    InputStream inputStream = null; 
    FileOutputStream fileOutputStream = null; 
    File file = null; 
    try { 
     downloadURL = new URL(URL); 
     httpURLConnection = (HttpURLConnection) downloadURL.openConnection(); 
     int responseCode = httpURLConnection.getResponseCode(); 
     if (responseCode != HttpURLConnection.HTTP_OK) 
      return; 
     inputStream = httpURLConnection.getInputStream(); 
     file = AppUtility.getInternalDirectoryForRhymes(this, rhymeName); 
     fileOutputStream = new FileOutputStream(file); 
     int read = -1; 
     long totalRead =0 ; 
     int totalLength = httpURLConnection.getContentLength(); 
     byte [] buffer = new byte[1024]; 
     while ((read = inputStream.read(buffer)) != -1) { 
      totalRead += read; 
      fileOutputStream.write(buffer, 0, read); 
      sendMyBroadCast(totalRead, totalLength, rhymeName); 
     } 
     successful = true; 
     UrduRhymesActivity.getInstance().unregisterMyReceiver(); 
     callListener(successful, rhymeName); 

    } catch (Exception e) { 
     if (e instanceof SocketTimeoutException) { 
      ProgressReceiver.showSocketConnectionDialogue(); 
     } 
     callListener(successful, rhymeName); 
    } finally { 
     if (httpURLConnection != null) { 
      httpURLConnection.disconnect(); 
     } 
     if (inputStream != null) { 
      try { 
       inputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     if (fileOutputStream != null) { 
      try { 
       fileOutputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

private void callListener(boolean successful, String rhymeName) { 
    ITaskCompletedListener taskCompletedListener = new ProgressReceiver(); 
    registerMyTaskCompletedListener(taskCompletedListener, successful, rhymeName); 
} 

}

下面是進步接收機

公共類ProgressReceiver擴展廣播接收器實現ITaskCompletedListener {

@Override 
public void onReceive(Context context, Intent intent) { 
    long currentProgress = intent.getLongExtra(Constants.UPDATED_VALUES, 0); 
    long totalSize = intent.getLongExtra(Constants.TOTAL_VIDEO_SIZE, 0); 
    String rhymeName = intent.getStringExtra(Constants.RHYME_NAME); 
    ProgressbarDetails progressbarDetails = ProgressbarDetails.getProgressDetail(rhymeName); 
    if (progressbarDetails != null) { 
     int updates = ((int) ((currentProgress/(float) totalSize) * 100)); 
     progressbarDetails.prgProgressBar.setVisibility(View.VISIBLE); 
     progressbarDetails.prgProgressBar.setProgress(updates); 
     LogUtility.infoLog("current downloaded file size is " + currentProgress); 
     LogUtility.infoLog("total file size " + totalSize); 
     LogUtility.infoLog("After conversion " + updates); 
    } 
} 

@Override 
public void taskCompleted(String rhymeName) { 
    runThread(rhymeName); 

} 

private void runThread(final String rhymeName) { 
    UrduRhymesActivity.getInstance().runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      ProgressbarDetails progressbarDetails = ProgressbarDetails.getProgressDetail(rhymeName); 
      progressbarDetails.download_btn_settings.setBackgroundResource(R.mipmap.btn_play); 
      progressbarDetails.prgProgressBar.setVisibility(View.GONE); 
      ProgressbarDetails.deleteUpdateProgressDetail(rhymeName); 

     } 
    }); 
} 

public static void showSocketConnectionDialogue() { 
    UrduRhymesActivity.getInstance().runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      //[Case:When server is down] 
      AppUtility.showConnectionDialoge(UrduRhymesActivity.sUrduRhymesActivity); 

     } 
    }); 
} 

@Override 
public void taskFailed(String rhymeName) { 
    boolean deleteStatus = false; 
    if (rhymeName != null) 
     deleteStatus = AppUtility.deleteFileFromInternalDirectory(MyApplication.getAppContext(), rhymeName); 
    if (deleteStatus) 
     LogUtility.infoLog("file deleted Successfully"); 
    else LogUtility.infoLog("File not deleted"); 

    ProgressbarDetails.deleteUpdateProgressDetail(rhymeName); 
} 

}

這裏是跟蹤下載狀態的主要代碼。

public class ProgressbarDetails { 

public ProgressBar prgProgressBar; 
public int progress; 
public LinearLayout download_btn_settings; 

private static HashMap<String, ProgressbarDetails> progressMapper = null; 

public static HashMap<String, ProgressbarDetails> getProgressMapper() { 
    if(progressMapper == null) 
     progressMapper = new HashMap<>(); 
    return progressMapper; 
} 

public static ProgressbarDetails getProgressDetail(String rhymeName) { 
    Object obj = getProgressMapper().get(rhymeName); 
    ProgressbarDetails ProgressbarDetails = null; 
    if (obj != null) 
     ProgressbarDetails = (ProgressbarDetails) obj; 

    return ProgressbarDetails; 
} 

public static void addUpdateProgressDetail(String rhymeName, ProgressbarDetails prgBarDetail) { 
    progressMapper = getProgressMapper(); 
    progressMapper.put(rhymeName, prgBarDetail); 
} 

public static void deleteUpdateProgressDetail(String rhymeName) { 
    progressMapper = getProgressMapper(); 
    if(progressMapper.containsKey(rhymeName)) 
     progressMapper.remove(rhymeName); 
} 

}

希望有所幫助。

+0

感謝您的快速回復。你能否提供一些代碼示例或者可能將我指向GIT存儲庫? –

+0

現在檢查我的更新答案。 –

+0

我會運行該代碼段,如果它能正常工作,肯定會批准並註冊。 –

0

這是我會怎麼做:

  1. 創建RecyclerView來保存每個上傳進度排
  2. 一旦啓動新的上傳 - 添加新項(行)的RecyclerView
  3. 您需要在RecyclerView行位置和它所表示的上傳任務之間保持某種映射(HashMap是一個不錯的選擇)
  4. 聽取你的任務的上傳進度(我看你有一個監聽器已經實現),並且當更新到達時 - 從步驟3查詢HashMap以檢查wh ich RecyclerView行需要更新。
  5. 用步驟4中的位置更新RecyclerView行。

一些資源,讓你開始:

Working with Recycler View

How to add new item to RecyclerView

How to update/refresh specific item in RecyclerView

Java HashMap class

+0

如果有幫助,它將檢查並更新您的密碼 –

+0

這不是完整的代碼 - 使用UI更新的整個機制非常複雜,無法在單個答案中編寫。但它應該指向您正確的方向來實現您提供的屏幕截圖和功能。祝你好運:) – mrsegev

相關問題