diff --git a/.idea/misc.xml b/.idea/misc.xml index 5d199810..fbb68289 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/task/IDownloadListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/task/IDownloadListener.java index d63d52b3..8d1c6271 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/task/IDownloadListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/task/IDownloadListener.java @@ -19,7 +19,7 @@ package com.arialyy.aria.core.download.task; /** * 下载监听 */ -public interface IDownloadListener { +interface IDownloadListener { /** * 支持断点回调 diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java index 9b9b2528..8fd5fa9b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.arialyy.aria.core.inf; /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java index 98f7e6ad..f8044a39 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java @@ -1,11 +1,69 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.arialyy.aria.core.upload; /** * Created by Aria.Lao on 2017/2/9. * 上传监听 */ - public interface IUploadListener { + /** + * 预处理 + */ + public void onPre(); + + /** + * 开始上传 + */ + public void onStart(long fileSize); + + /** + * 恢复上传 + * + * @param resumeLocation 上次上传停止位置 + */ + public void onResume(long resumeLocation); + + /** + * 停止上传 + * + * @param stopLocation 上传停止位置 + */ + public void onStop(long stopLocation); + + /** + * 上传进度 + * + * @param currentLocation 当前进度 + */ + public void onProgress(long currentLocation); + + /** + * 取消上传 + */ + public void onCancel(); + + /** + * 上传成功 + */ + public void onComplete(); + + /** + * 上传失败 + */ public void onFail(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/MultipartUtility.java b/Aria/src/main/java/com/arialyy/aria/core/upload/MultipartUtility.java deleted file mode 100644 index fa6cd613..00000000 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/MultipartUtility.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.arialyy.aria.core.upload; - -import android.util.Log; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; - -public class MultipartUtility { - - private final String boundary; - private static final String LINE_FEED = "\r\n"; - private HttpURLConnection httpConn; - private String charset; - private OutputStream outputStream; - private PrintWriter writer; - - /** - * 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(String requestURL, String charset) - throws IOException { - this.charset = charset; - - // creates a unique boundary based on time stamp - boundary = "===" + System.currentTimeMillis() + "==="; - - URL url = new URL(requestURL); - Log.e("URL", "URL : " + requestURL.toString()); - httpConn = (HttpURLConnection) url.openConnection(); - httpConn.setUseCaches(false); - httpConn.setDoOutput(true); // indicates POST method - httpConn.setDoInput(true); - httpConn.setRequestProperty("Content-Type", - "multipart/form-data; boundary=" + boundary); - httpConn.setRequestProperty("User-Agent", "CodeJava Agent"); - httpConn.setRequestProperty("Test", "Bonjour"); - outputStream = httpConn.getOutputStream(); - writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), - true); - } - - /** - * 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 - * @param uploadFile a File to be uploaded - * @throws IOException - */ - 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("Content-Transfer-Encoding: binary").append(LINE_FEED); - writer.append(LINE_FEED); - writer.flush(); - - FileInputStream inputStream = new FileInputStream(uploadFile); - byte[] buffer = new byte[4096]; - int bytesRead = -1; - while ((bytesRead = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - outputStream.flush(); - inputStream.close(); - - 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 finish() throws IOException { - StringBuffer response = new StringBuffer(); - - writer.append(LINE_FEED).flush(); - writer.append("--" + boundary + "--").append(LINE_FEED); - writer.close(); - - // checks server's status code first - int status = httpConn.getResponseCode(); - if (status == HttpURLConnection.HTTP_OK) { - BufferedReader reader = new BufferedReader(new InputStreamReader( - httpConn.getInputStream())); - String line = null; - while ((line = reader.readLine()) != null) { - response.append(line); - } - reader.close(); - httpConn.disconnect(); - } else { - throw new IOException("Server returned non-OK status: " + status); - } - - return response.toString(); - } -} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java index 014aba7a..f9a251e2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java @@ -11,6 +11,7 @@ public class UploadEntity { private String filePath; //文件路径 private String fileName; //文件名 + private long fileSize; //文件大小 public String getFilePath() { return filePath; diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java index 0db4c2eb..57ea3b35 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java @@ -3,6 +3,7 @@ package com.arialyy.aria.core.upload; import android.util.Log; import com.arialyy.aria.util.CheckUtil; import java.io.BufferedReader; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -22,20 +23,24 @@ import java.util.UUID; * 上传工具 */ public class UploadUtil implements Runnable { - private static final String TAG = "UploadUtil"; - private final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 - private final String PREFIX = "--", LINE_END = "\r\n"; - private UploadEntity mUploadEntity; - private UploadTaskEntity mTaskEntity; - private IUploadListener mListener; - private PrintWriter mWriter; - private OutputStream mOutputStream; + private static final String TAG = "UploadUtil"; + private final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 + private final String PREFIX = "--", LINE_END = "\r\n"; + private UploadEntity mUploadEntity; + private UploadTaskEntity mTaskEntity; + private IUploadListener mListener; + private PrintWriter mWriter; + private OutputStream mOutputStream; private HttpURLConnection mHttpConn; + private long mCurrentLocation = 0; public UploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) { mTaskEntity = taskEntity; CheckUtil.checkUploadEntity(taskEntity.uploadEntity); mUploadEntity = taskEntity.uploadEntity; + if (listener == null) { + throw new IllegalArgumentException("上传监听不能为空"); + } mListener = listener; } @@ -44,22 +49,27 @@ public class UploadUtil implements Runnable { } @Override public void run() { - File file = new File(mUploadEntity.getFilePath()); - if (!file.exists()) { + File uploadFile = new File(mUploadEntity.getFilePath()); + if (!uploadFile.exists()) { Log.e(TAG, "【" + mUploadEntity.getFilePath() + "】,文件不存在。"); mListener.onFail(); return; } + mListener.onPre(); + URL url = null; try { url = new URL(mTaskEntity.uploadUrl); mHttpConn = (HttpURLConnection) url.openConnection(); mHttpConn.setUseCaches(false); - mHttpConn.setDoOutput(true); // indicates POST method + mHttpConn.setDoOutput(true); mHttpConn.setDoInput(true); mHttpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); mHttpConn.setRequestProperty("User-Agent", "CodeJava Agent"); + //内部缓冲区---分段上传防止oom + //System.setProperty("http.keepAlive", "false"); + mHttpConn.setChunkedStreamingMode(1024); //添加Http请求头部 Set keys = mTaskEntity.headers.keySet(); @@ -75,10 +85,9 @@ public class UploadUtil implements Runnable { for (String key : keys) { addFormField(key, mTaskEntity.formFields.get(key)); } - - addFilePart(mTaskEntity.attachment, new File(mUploadEntity.getFilePath())); + mListener.onStart(uploadFile.length()); + addFilePart(mTaskEntity.attachment, uploadFile); Log.d(TAG, finish() + ""); - finish(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { @@ -89,7 +98,7 @@ public class UploadUtil implements Runnable { /** * 添加文件上传表单字段 */ - public void addFormField(String name, String value) { + private void addFormField(String name, String value) { mWriter.append(PREFIX).append(BOUNDARY).append(LINE_END); mWriter.append("Content-Disposition: form-data; name=\"") .append(name) @@ -109,7 +118,7 @@ public class UploadUtil implements Runnable { * @param fieldName 文件上传attachment * @throws IOException */ - public void addFilePart(String fieldName, File uploadFile) throws IOException { + private void addFilePart(String fieldName, File uploadFile) throws IOException { String fileName = uploadFile.getName(); mWriter.append(PREFIX).append(BOUNDARY).append(LINE_END); mWriter.append("Content-Disposition: form-data; name=\"") @@ -126,14 +135,16 @@ public class UploadUtil implements Runnable { mWriter.flush(); FileInputStream inputStream = new FileInputStream(uploadFile); - byte[] buffer = new byte[4096]; + byte[] buffer = new byte[1024]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { + mCurrentLocation += bytesRead; mOutputStream.write(buffer, 0, bytesRead); + mListener.onProgress(mCurrentLocation); } mOutputStream.flush(); inputStream.close(); - + mListener.onComplete(); mWriter.append(LINE_END); mWriter.flush(); } @@ -143,14 +154,13 @@ public class UploadUtil implements Runnable { * * @throws IOException */ - public String finish() throws IOException { + private String finish() throws IOException { StringBuilder response = new StringBuilder(); mWriter.append(LINE_END).flush(); mWriter.append(PREFIX).append(BOUNDARY).append(PREFIX).append(LINE_END); mWriter.close(); - // checks server's status code first int status = mHttpConn.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader(mHttpConn.getInputStream())); @@ -166,6 +176,4 @@ public class UploadUtil implements Runnable { return response.toString(); } - - } diff --git a/app/src/main/java/com/arialyy/simple/upload.java b/app/src/main/java/com/arialyy/simple/upload.java index 29f3bd99..bdf1a22d 100644 --- a/app/src/main/java/com/arialyy/simple/upload.java +++ b/app/src/main/java/com/arialyy/simple/upload.java @@ -1,36 +1,71 @@ package com.arialyy.simple; import android.view.View; +import android.widget.ProgressBar; +import butterknife.Bind; import com.arialyy.aria.core.upload.IUploadListener; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTaskEntity; import com.arialyy.aria.core.upload.UploadUtil; import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.ActivityUploadBinding; +import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; /** * Created by Aria.Lao on 2017/2/9. */ -public class upload extends BaseActivity{ +public class upload extends BaseActivity { + + @Bind(R.id.pb) HorizontalProgressBarWithNumber mPb; + @Override protected int setLayoutId() { return R.layout.activity_upload; - } - public void onClick(View view){ + public void onClick(View view) { UploadEntity entity = new UploadEntity(); - entity.setFilePath("/sdcard/Download/test.pdf"); + entity.setFilePath("/sdcard/Download/test.zip"); entity.setFileName("test.pdf"); UploadTaskEntity taskEntity = new UploadTaskEntity(entity); - taskEntity.uploadUrl = "http://192.168.1.9:8080/upload/sign_file"; + taskEntity.uploadUrl = "http://172.18.104.189:8080/upload/sign_file"; taskEntity.attachment = "file"; UploadUtil util = new UploadUtil(taskEntity, new IUploadListener() { + long fileSize = 0; + + @Override public void onPre() { + + } + + @Override public void onStart(long fileSize) { + this.fileSize = fileSize; + } + + @Override public void onResume(long resumeLocation) { + + } + + @Override public void onStop(long stopLocation) { + + } + + @Override public void onProgress(long currentLocation) { + int p = (int) (currentLocation * 100 / fileSize); + mPb.setProgress(p); + } + + @Override public void onCancel() { + + } + + @Override public void onComplete() { + + } + @Override public void onFail() { } }); util.start(); } - } diff --git a/app/src/main/res/layout/activity_upload.xml b/app/src/main/res/layout/activity_upload.xml index 9782fff3..ca16a099 100644 --- a/app/src/main/res/layout/activity_upload.xml +++ b/app/src/main/res/layout/activity_upload.xml @@ -17,6 +17,15 @@ style="?buttonBarButtonStyle" /> + +