में प्रगति कॉलबैक के साथ क्लाउडिनरी में एक फोटो अपलोड करना मैं क्लाउडिनरी की ओपन सोर्स लाइब्रेरी को संशोधित करने की कोशिश कर रहा हूं ताकि मैं अपनी तस्वीर के अपलोड की प्रगति को सुन सकूं। लाइब्रेरी क्लास में एक मल्टीपार्ट यूटिलिटी जावा क्लास है जिसे मैंने अपलोड की प्रगति को सुनने के लिए संशोधित किया है। https://github.com/cloudinary/cloudinary_java/blob/master/cloudinary-android/src/main/java/com/cloudinary/android/MultipartUtility.javaएंड्रॉइड: HttpURLConnection
मैं सचमुच इसे संशोधित एक और क्लाउड सेवा CloudFS से कोड जब फ़ाइलें/छवियों आदि अपलोड करने पर काम चल रहा का समर्थन करता है के समान:
संशोधनों से पहले मूल कोड GitHub पर पाया जा सकता है
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 charset, 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, 0, 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, inputStream, "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, 0, bytesRead);
progress += bytesRead;
/* int percentage = ((progress/filesize.intValue()) * 100);*/
if (uploadingCallback != null) {
uploadingCallback.uploadListener(progress);
}
}
कोड भाग गया लेकिन प्रगति अपलोड का सही ढंग से मापा नहीं प्रतीत होता है। तस्वीर लगभग 365 केबी थी और अपलोड में एक सेकंड का 10 वां हिस्सा था (मैंने 17: 56: 55.481 पर अपलोड शुरू किया और 17: 56: 55.554 यह किया गया था, यह सिर्फ 0.7 सेकेंड से अधिक है)। मुझे विश्वास नहीं है कि मेरा इंटरनेट कनेक्शन तेज़ है और कम से कम 5 सेकंड लेने की उम्मीद है। मुझे लगता है कि यह क्लाउडिनरी सर्वर पर भेजने के लिए बफर को फोटो लिखने के लिए लगाए गए समय को माप रहा है।
तस्वीर अपलोड करने में लगने वाले समय को मापने के लिए मैं इसे कैसे प्राप्त कर सकता हूं ताकि मैं अपनी प्रगति पट्टी के लिए डेटा का उपयोग कर सकूं?
04-24 17:56:55.481 28306-28725/com.a upload 4096
04-24 17:56:55.486 28306-28725/com.a upload 8192
04-24 17:56:55.486 28306-28725/com.a upload 12288
04-24 17:56:55.486 28306-28725/com.a upload 16384
04-24 17:56:55.487 28306-28725/com.a upload 20480
04-24 17:56:55.487 28306-28725/com.a upload 24576
04-24 17:56:55.487 28306-28725/com.a upload 28672
04-24 17:56:55.487 28306-28725/com.a upload 32768
04-24 17:56:55.491 28306-28725/com.a upload 36864
04-24 17:56:55.492 28306-28725/com.a upload 40960
04-24 17:56:55.493 28306-28725/com.a upload 45056
04-24 17:56:55.493 28306-28725/com.a upload 49152
04-24 17:56:55.493 28306-28725/com.a upload 53248
04-24 17:56:55.493 28306-28725/com.a upload 57344
04-24 17:56:55.494 28306-28725/com.a upload 61440
04-24 17:56:55.494 28306-28725/com.a upload 65536
04-24 17:56:55.494 28306-28725/com.a upload 69632
04-24 17:56:55.494 28306-28725/com.a upload 73728
04-24 17:56:55.494 28306-28725/com.a upload 77824
04-24 17:56:55.495 28306-28725/com.a upload 81920
04-24 17:56:55.495 28306-28725/com.a upload 86016
04-24 17:56:55.495 28306-28725/com.a upload 90112
04-24 17:56:55.495 28306-28725/com.a upload 94208
04-24 17:56:55.495 28306-28725/com.a upload 98304
04-24 17:56:55.495 28306-28725/com.a upload 102400
04-24 17:56:55.495 28306-28725/com.a upload 106496
04-24 17:56:55.496 28306-28725/com.a upload 110592
04-24 17:56:55.496 28306-28725/com.a upload 114688
04-24 17:56:55.496 28306-28725/com.a upload 118784
04-24 17:56:55.497 28306-28725/com.a upload 122880
04-24 17:56:55.498 28306-28725/com.a upload 126976
04-24 17:56:55.498 28306-28725/com.a upload 131072
04-24 17:56:55.498 28306-28725/com.a upload 135168
04-24 17:56:55.498 28306-28725/com.a upload 139264
04-24 17:56:55.499 28306-28725/com.a upload 143360
04-24 17:56:55.506 28306-28725/com.a upload 147456
04-24 17:56:55.510 28306-28725/com.a upload 151552
04-24 17:56:55.510 28306-28725/com.a upload 155648
04-24 17:56:55.514 28306-28725/com.a upload 159744
04-24 17:56:55.515 28306-28725/com.a upload 163840
04-24 17:56:55.517 28306-28725/com.a upload 167936
04-24 17:56:55.517 28306-28725/com.a upload 172032
04-24 17:56:55.518 28306-28725/com.a upload 176128
04-24 17:56:55.518 28306-28725/com.a upload 180224
04-24 17:56:55.518 28306-28725/com.a upload 184320
04-24 17:56:55.519 28306-28725/com.a upload 188416
04-24 17:56:55.519 28306-28725/com.a upload 192512
04-24 17:56:55.519 28306-28725/com.a upload 196608
04-24 17:56:55.519 28306-28725/com.a upload 200704
04-24 17:56:55.520 28306-28725/com.a upload 204800
04-24 17:56:55.525 28306-28725/com.a upload 208896
04-24 17:56:55.526 28306-28725/com.a upload 212992
04-24 17:56:55.527 28306-28725/com.a upload 217088
04-24 17:56:55.530 28306-28725/com.a upload 221184
04-24 17:56:55.530 28306-28725/com.a upload 225280
04-24 17:56:55.530 28306-28725/com.a upload 229376
04-24 17:56:55.530 28306-28725/com.a upload 233472
04-24 17:56:55.530 28306-28725/com.a upload 237568
04-24 17:56:55.531 28306-28725/com.a upload 241664
04-24 17:56:55.532 28306-28725/com.a upload 245760
04-24 17:56:55.532 28306-28725/com.a upload 249856
04-24 17:56:55.532 28306-28725/com.a upload 253952
04-24 17:56:55.533 28306-28725/com.a upload 258048
04-24 17:56:55.533 28306-28725/com.a upload 262144
04-24 17:56:55.535 28306-28725/com.a upload 266240
04-24 17:56:55.540 28306-28725/com.a upload 270336
04-24 17:56:55.540 28306-28725/com.a upload 274432
04-24 17:56:55.541 28306-28725/com.a upload 278528
04-24 17:56:55.541 28306-28725/com.a upload 282624
04-24 17:56:55.543 28306-28725/com.a upload 286720
04-24 17:56:55.545 28306-28725/com.a upload 290816
04-24 17:56:55.545 28306-28725/com.a upload 294912
04-24 17:56:55.547 28306-28725/com.a upload 299008
04-24 17:56:55.547 28306-28725/com.a upload 303104
04-24 17:56:55.547 28306-28725/com.a upload 307200
04-24 17:56:55.547 28306-28725/com.a upload 311296
04-24 17:56:55.547 28306-28725/com.a upload 315392
04-24 17:56:55.548 28306-28725/com.a upload 319488
04-24 17:56:55.548 28306-28725/com.a upload 323584
04-24 17:56:55.548 28306-28725/com.a upload 327680
04-24 17:56:55.548 28306-28725/com.a upload 331776
04-24 17:56:55.549 28306-28725/com.a upload 335872
04-24 17:56:55.549 28306-28725/com.a upload 339968
04-24 17:56:55.549 28306-28725/com.a upload 344064
04-24 17:56:55.550 28306-28725/com.a upload 348160
04-24 17:56:55.550 28306-28725/com.a upload 352256
04-24 17:56:55.551 28306-28725/com.a upload 356352
04-24 17:56:55.551 28306-28725/com.a upload 360448
04-24 17:56:55.552 28306-28725/com.a upload 364544
04-24 17:56:55.554 28306-28725/com.a upload 365790
खुद के लिए यह परीक्षण करने के लिए, आप cloudinary वेबसाइट पर एक मुक्त खाता क्रम में अपने cloudname
ताकि आप अपने Android एसडीके उनकी सेवाओं के लिए एंड्रॉयड से एक अहस्ताक्षरित प्रत्यक्ष अपलोड करने के लिए सीधे कनेक्ट कर सकते हैं पाने के लिए बनाने की आवश्यकता होगी उनके सर्वर
संपादित करें:
यह है कि मैं क्या करने की कोशिश की है और यह अभी भी 0 से कूदता है - 0.7 सेकंड में 100% जब अपलोड वास्तव में 7 सेकंड समय में खत्म:
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, 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();
}
आपका दूसरा विकल्प बहुत कम समझ में आता है, क्योंकि वह भी होगा के लिए एक प्रगति संकेतक प्राप्त करने के लिए 100% और मुझे क्या करना कोशिश कर रहा हूँ है का पूरा उद्देश्य पर होना अपलोड करें। मैंने आपके पहले विकल्प की कोशिश की और यह काम नहीं कर रहा है, मैंने यह दिखाने के लिए एक संपादन किया है कि मैंने कोशिश की है कि मैंने कोशिश की है। – Simon
आपको ug__ प्रस्ताव की तरह कुछ करने की आवश्यकता है। आपको थोड़ी देर में फ्लश() को कॉल करना चाहिए :), लेकिन जैसा कि मैं आपके परिवर्तन से देख सकता हूं, यह आपके लिए भी काम नहीं कर रहा है। मुझे इसका परीक्षण करने और आपको बताने की आवश्यकता होगी, लेकिन मुझे 99% यकीन है कि फ्लश() को कॉल करना सही तरीका है। हो सकता है कि आपके कोड के किसी अन्य भाग में समस्या हो। इसका परीक्षण करने की आवश्यकता होगी, जो मैं तुरंत करूँगा। – aleksamarkoni
तकनीकी रूप से, आउटपुटस्ट्रीम पर फ्लश कॉल करना कुछ भी नहीं करेगा क्योंकि दस्तावेज़ कहते हैं कि यह कुछ भी नहीं करता है: https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html#flush() I ' मैं इसे डेटाऑटपुटस्ट्रीम पर कास्टिंग कर रहा हूं यह देखने के लिए कि क्या इससे कोई फर्क पड़ता है। यह वास्तव में कोई फर्क नहीं पड़ता है। – Simon