0

I have written following code to upload a wav file over server , the problem i am facing is the progress bar moves too fast till 99% and complets onces the server returns 200 OK response.

but i have seen in dropbox while i upload a file i can see the progress bar is moving gradually and looks convincing.

anyone has an idea how do i show seamless progress bar.

    @Override
        protected String doInBackground(Void...args) {
            // TODO Auto-generated method stub


            System.out.println(uploadLink);
            FileInputStream sourceFile = null;

            try {
                sourceFile = new FileInputStream(to);
            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }




            URL url;
            try {

                byte[] bytes = new byte[(int) to.length()];
                sourceFile.read(bytes);


                url = new URL(uploadLink);
                connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setUseCaches(false);
                connection.setRequestMethod("POST");    

                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
                out = new DataOutputStream( connection.getOutputStream() );
                out.writeBytes(twoHyphens + boundary + lineEnd);                
                out.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + templateID + ".wav" + "\"" + lineEnd);
                out.writeBytes(lineEnd);
                bytesAvailable = sourceFile.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                buffer = new byte[bufferSize];

                Log.d("BYTES" , bytesAvailable + " "+bufferSize +" "+  bytes.length);

                int bufferLength = 1024;

                for (int i = 0; i < bytes.length; i += bufferLength) {

                    int progress = (int)((i / (float) bytes.length) * 100);
                    publishProgress(progress);

                    if (bytes.length - i >= bufferLength) {
                        out.write(bytes, i, bufferLength);
                    } else {
                        out.write(bytes, i, bytes.length - i);
                    }
                }


               out.writeBytes(lineEnd);
               out.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
               sourceFile.close();
               out.flush();
               out.close();            



            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();



                return null;
            } 
             try {
                 in = new DataInputStream ( connection.getInputStream() );
                 String str;

                 Log.d("STATUS",connection.getResponseCode()+ " ");

                 if(connection.getResponseCode() == 200)
                 {                   
                     while (( str = in.readLine()) != null)
                     {
                      Log.e("Debug","Server Response "+str);
                      publishProgress(100);





                     }
                 }


                 in.close();

           }
           catch (IOException ioex){
                Log.e("Debug", "error: " + ioex.getMessage(), ioex);
           }

            // Get the source File


            return "success";
        }
Hunt
  • 8,215
  • 28
  • 116
  • 256

3 Answers3

1

I also struggled to accomplish this, with the client always saying that the progress wasn't real.

The solution that I found was using setFixedLengthStreamingMode in the HttpURLConnection object (see more about setFixedLengthStreamingMode here). Basically what this does is that Content-Length header is set much sooner, so URLConnection can flush more often.

Your code should be something like this:

String header = twoHyphens + boundary + lineEnd + "Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + templateID + ".wav" + "\"" + lineEnd + lineEnd;
String closingHeader = lineEnd + twoHyphens + boundary + twoHyphens + lineEnd;

int bytesToBeSent = header.lenght() + closingHeader.lenght() + (int)to.length();

connection.setFixedLengthStreamingMode(bytesToBeSent);

This must be set before you use setRequestMethod().

Community
  • 1
  • 1
pepipe
  • 61
  • 8
  • i tried your code but i am getting error at `out.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);` error is `java.io.IOException: expected 9 bytes but received 11` – Hunt Mar 05 '13 at 05:49
  • `String closingHeader = lineEnd + twoHyphens + boundary + twoHyphens + lineEnd;` I was missing a twoHyphens but the bottomline of this solution is that you need to pass to setFixedLengthStreamingMode all the bytes that you will be sending. And why you not do out.writeBytes(header) and out.writeBytes(closingHeader) ? – pepipe Mar 05 '13 at 18:59
0

If it's fast, it's fast, no? The only thing I would suggest is to call publishProgress(100); once you finish uploading, not until you get the response.

dmon
  • 30,048
  • 8
  • 87
  • 96
  • then how can we sure that file is uploaded successfully and if i set use `publishProgress` before that it movie damn fast and finished in a sec – Hunt Jan 22 '13 at 19:02
  • Publish progress will just update the progress bar... You can still have something that says it's still "uploading" or "waiting for server response". In any case, what you can measure is gone. – dmon Jan 22 '13 at 19:05
  • i have already put that but thts not an issue , problem is it doesnt look convincing n real – Hunt Jan 23 '13 at 08:48
  • Well then, if reality is too fast for you, add a `Thread.sleep()`! ¬¬ – dmon Jan 23 '13 at 14:47
  • so u mean to say there isnt any way that we can show progress bar till we get the confirmation from server that the file has been uploaded – Hunt Jan 23 '13 at 17:27
  • Well, obviously not with the progress bar only, since the progress bar can only show you the upload progress, which IS completed before you get the response back. – dmon Jan 23 '13 at 17:56
-1

The key is setChunkedStreamingMode(). You need to set it to your file length before setRequestMethod(). This will send the bytes in chunks and will give you a feel of progress in progress bar. After you've set that, you can use the code provided in the question.

Atlas01
  • 11
  • 3