
修改前的原始代码可以在github:https://github.com/cloudinary/cloudinary_java/blob/master/cloudinary-android/src/main/java/com/cloudinary/android/MultipartUtility.java上找到
我将其修改为类似于另一个云服务CloudFS的代码,该代码在上传文件/图像等时支持进度:
https://github.com/bitcasa/CloudFS-Android/blob/master/app/src/main/java/com/bitcasa/cloudfs/api/MultipartUpload.java
package com.cloudinary.androID;import com.cloudinary.Cloudinary;import java.io.*;import java.net.httpURLConnection;import java.net.URL;import java.util.Map;/** * This utility class provIDes an abstraction layer for sending multipart http * POST requests to a web server. * * @author www.codejava.net * @author Cloudinary */public class MultipartUtility { private final String boundary; private static final String liNE_Feed = "\r\n"; private static final String APPliCATION_OCTET_STREAM = "application/octet-stream"; private httpURLConnection httpConn; private String charset; private OutputStream outputStream; private PrintWriter writer; UploadingCallback uploadingCallback; public final static String USER_AGENT = "CloudinaryAndroID/" + Cloudinary.VERSION; Long filesize; public voID setUploadingCallback(UploadingCallback uploadingCallback) { this.uploadingCallback = uploadingCallback; } /** * 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,String boundary,Map<String,String> headers,Long filesize) throws IOException { this.charset = charset; this.boundary = boundary; this.filesize = filesize; URL url = new URL(requestURL); httpConn = (httpURLConnection) url.openConnection(); httpConn.setDoOutput(true); // indicates POST method httpConn.setDoinput(true); httpConn.setFixedLengthStreamingMode(filesize); //added this in if (headers != null) { for (Map.Entry<String,String> header : headers.entrySet()) { httpConn.setRequestProperty(header.getKey(),header.getValue()); } } httpConn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary); httpConn.setRequestProperty("User-Agent",USER_AGENT); outputStream = httpConn.getoutputStream(); writer = new PrintWriter(new OutputStreamWriter(outputStream,charset),true); } public MultipartUtility(String requestURL,String boundary) throws IOException { this(requestURL,charset,boundary,null,0L); } /** * 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 {@code <input type="file" name="..." />} * @param uploadfile a file to be uploaded * @throws IOException */ public voID addfilePart(String fIEldname,file uploadfile,String filename) throws IOException { if (filename == null) filename = uploadfile.getname(); fileinputStream inputStream = new fileinputStream(uploadfile); addfilePart(fIEldname,inputStream,filename); } public voID addfilePart(String fIEldname,file uploadfile) throws IOException { addfilePart(fIEldname,uploadfile,"file"); } public voID addfilePart(String fIEldname,inputStream inputStream,String filename) throws IOException { if (filename == null) filename = "file"; writer.append("--" + boundary).append(liNE_Feed); writer.append("Content-disposition: form-data; name=\"" + fIEldname + "\"; filename=\"" + filename + "\"").append(liNE_Feed); writer.append("Content-Type: ").append(APPliCATION_OCTET_STREAM).append(liNE_Feed); writer.append("Content-transfer-encoding: binary").append(liNE_Feed); writer.append(liNE_Feed); writer.flush(); int progress = 0; byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer,bytesRead); progress += bytesRead;/* int percentage = ((progress / filesize.intValue()) * 100);*/ if (uploadingCallback != null) { uploadingCallback.uploadListener(progress); } } outputStream.flush(); writer.flush(); uploadingCallback = null; inputStream.close(); writer.append(liNE_Feed); writer.flush(); } public voID addfilePart(String fIEldname,inputStream inputStream) throws IOException { addfilePart(fIEldname,"file"); } /** * 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 httpURLConnection execute() throws IOException { writer.append("--" + boundary + "--").append(liNE_Feed); writer.close(); return httpConn; }} 我所做的更改是按照此线程的建议将以下内容添加到httpURLConnection:How to implement file upload progress bar in android:httpConn.setFixedLengthStreamingMode(filesize);
然后我创建了一个简单的界面来监听上传进度:
public interface UploadingCallback { voID uploadListener(int progress);} 然后我在httpURLConnection写下照片时附上它:
while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer,bytesRead); progress += bytesRead;/* int percentage = ((progress / filesize.intValue()) * 100);*/ if (uploadingCallback != null) { uploadingCallback.uploadListener(progress); } } 代码已运行,但上传的进度似乎没有正确测量.这张照片大概是365kb,上传时间大约是十分之一秒(我开始上传时间为17:56:55.481,17:56:55.554已完成上传,这只是超过0.7秒).我不相信我的互联网连接速度很快,并且预计它至少需要5秒钟.我感觉它正在测量将照片写入缓冲区所花费的时间,而不是将它发送到cloudinary服务器所花费的时间.
我怎样才能测量上传照片所需的时间,以便我可以将数据用于进度条?
04-24 17:56:55.481 28306-28725/com.a upload 409604-24 17:56:55.486 28306-28725/com.a upload 819204-24 17:56:55.486 28306-28725/com.a upload 1228804-24 17:56:55.486 28306-28725/com.a upload 1638404-24 17:56:55.487 28306-28725/com.a upload 2048004-24 17:56:55.487 28306-28725/com.a upload 2457604-24 17:56:55.487 28306-28725/com.a upload 2867204-24 17:56:55.487 28306-28725/com.a upload 3276804-24 17:56:55.491 28306-28725/com.a upload 3686404-24 17:56:55.492 28306-28725/com.a upload 4096004-24 17:56:55.493 28306-28725/com.a upload 4505604-24 17:56:55.493 28306-28725/com.a upload 4915204-24 17:56:55.493 28306-28725/com.a upload 5324804-24 17:56:55.493 28306-28725/com.a upload 5734404-24 17:56:55.494 28306-28725/com.a upload 6144004-24 17:56:55.494 28306-28725/com.a upload 6553604-24 17:56:55.494 28306-28725/com.a upload 6963204-24 17:56:55.494 28306-28725/com.a upload 7372804-24 17:56:55.494 28306-28725/com.a upload 7782404-24 17:56:55.495 28306-28725/com.a upload 8192004-24 17:56:55.495 28306-28725/com.a upload 8601604-24 17:56:55.495 28306-28725/com.a upload 9011204-24 17:56:55.495 28306-28725/com.a upload 9420804-24 17:56:55.495 28306-28725/com.a upload 9830404-24 17:56:55.495 28306-28725/com.a upload 10240004-24 17:56:55.495 28306-28725/com.a upload 10649604-24 17:56:55.496 28306-28725/com.a upload 11059204-24 17:56:55.496 28306-28725/com.a upload 11468804-24 17:56:55.496 28306-28725/com.a upload 11878404-24 17:56:55.497 28306-28725/com.a upload 12288004-24 17:56:55.498 28306-28725/com.a upload 12697604-24 17:56:55.498 28306-28725/com.a upload 13107204-24 17:56:55.498 28306-28725/com.a upload 13516804-24 17:56:55.498 28306-28725/com.a upload 13926404-24 17:56:55.499 28306-28725/com.a upload 14336004-24 17:56:55.506 28306-28725/com.a upload 14745604-24 17:56:55.510 28306-28725/com.a upload 15155204-24 17:56:55.510 28306-28725/com.a upload 15564804-24 17:56:55.514 28306-28725/com.a upload 15974404-24 17:56:55.515 28306-28725/com.a upload 16384004-24 17:56:55.517 28306-28725/com.a upload 16793604-24 17:56:55.517 28306-28725/com.a upload 17203204-24 17:56:55.518 28306-28725/com.a upload 17612804-24 17:56:55.518 28306-28725/com.a upload 18022404-24 17:56:55.518 28306-28725/com.a upload 18432004-24 17:56:55.519 28306-28725/com.a upload 18841604-24 17:56:55.519 28306-28725/com.a upload 19251204-24 17:56:55.519 28306-28725/com.a upload 19660804-24 17:56:55.519 28306-28725/com.a upload 20070404-24 17:56:55.520 28306-28725/com.a upload 20480004-24 17:56:55.525 28306-28725/com.a upload 20889604-24 17:56:55.526 28306-28725/com.a upload 21299204-24 17:56:55.527 28306-28725/com.a upload 21708804-24 17:56:55.530 28306-28725/com.a upload 22118404-24 17:56:55.530 28306-28725/com.a upload 22528004-24 17:56:55.530 28306-28725/com.a upload 22937604-24 17:56:55.530 28306-28725/com.a upload 23347204-24 17:56:55.530 28306-28725/com.a upload 23756804-24 17:56:55.531 28306-28725/com.a upload 24166404-24 17:56:55.532 28306-28725/com.a upload 24576004-24 17:56:55.532 28306-28725/com.a upload 24985604-24 17:56:55.532 28306-28725/com.a upload 25395204-24 17:56:55.533 28306-28725/com.a upload 25804804-24 17:56:55.533 28306-28725/com.a upload 26214404-24 17:56:55.535 28306-28725/com.a upload 26624004-24 17:56:55.540 28306-28725/com.a upload 27033604-24 17:56:55.540 28306-28725/com.a upload 27443204-24 17:56:55.541 28306-28725/com.a upload 27852804-24 17:56:55.541 28306-28725/com.a upload 28262404-24 17:56:55.543 28306-28725/com.a upload 28672004-24 17:56:55.545 28306-28725/com.a upload 29081604-24 17:56:55.545 28306-28725/com.a upload 29491204-24 17:56:55.547 28306-28725/com.a upload 29900804-24 17:56:55.547 28306-28725/com.a upload 30310404-24 17:56:55.547 28306-28725/com.a upload 30720004-24 17:56:55.547 28306-28725/com.a upload 31129604-24 17:56:55.547 28306-28725/com.a upload 31539204-24 17:56:55.548 28306-28725/com.a upload 31948804-24 17:56:55.548 28306-28725/com.a upload 32358404-24 17:56:55.548 28306-28725/com.a upload 32768004-24 17:56:55.548 28306-28725/com.a upload 33177604-24 17:56:55.549 28306-28725/com.a upload 33587204-24 17:56:55.549 28306-28725/com.a upload 33996804-24 17:56:55.549 28306-28725/com.a upload 34406404-24 17:56:55.550 28306-28725/com.a upload 34816004-24 17:56:55.550 28306-28725/com.a upload 35225604-24 17:56:55.551 28306-28725/com.a upload 35635204-24 17:56:55.551 28306-28725/com.a upload 36044804-24 17:56:55.552 28306-28725/com.a upload 36454404-24 17:56:55.554 28306-28725/com.a upload 365790
要自己测试一下,您需要在cloudinary网站上创建一个免费帐户以获取您的云端名称,这样您就可以将AndroID SDK连接到他们的服务,从而直接从AndroID直接上传到他们的服务器.
编辑:
这是我尝试过的,当上传实际在7秒内完成时,它仍然会在0.7秒内从0 – 100%跳跃:
while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer,bytesRead); progress += bytesRead; Log.d("MultiPart","file transferred so far: " + progress); if (uploadingCallback != null) { uploadingCallback.uploadListener(progress); } Log.d("Flushing","flush the writer"); outputStream.flush(); writer.flush(); }解决方法 使用flush()方法和调用update callback()的时间有问题. 每次读取部分图片时都可以从代码中看到,将其写入输出缓冲区,但这并不意味着它被发送到服务器,它可能被缓冲,然后写入服务器.
你有两个选择,在每个outputStream.write()之后调用outputStream.flush(),但这会杀死上传的性能,因为你会失去缓冲的好处.
或者,您可以在方法结束时的outputStream.flush()之后调用updateCallback().因为在outputStream.flush()之后,您确定数据在服务器上,并且该进度已结束.
有关flush的更多信息,请参阅此主题What is the purpose of flush() in Java streams?
总结以上是内存溢出为你收集整理的java – Android:使用HttpURLConnection中的进度回调在Cloudinary中上传照片全部内容,希望文章能够帮你解决java – Android:使用HttpURLConnection中的进度回调在Cloudinary中上传照片所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)