1

I want to upload an image to my server. Therfore i've build this and sending to the server works quite well. Yet one thing is missing, which is ProgressDialog. I tried a lot of ways but don't know how to do it the right way. I call ImageUploader.uploadFile() in an AsyncTask in the preExecute method at the moment.

As within the doInBackground i have to send an E-mail which has the photo as attachment with it. So the photo needs to be uploaded before it's attached to the email. So how to do this and how to show the ProgressDialog?

This is how I Call the function:

       @Override
        protected void onPreExecute(){
            super.onPreExecute();
            if(isPhotoTaken()){
                ImageUploader.uploadFile(getPhotoPath(), "http://www.example.com/upload.php", Step4.this);              
            }
        }

This is my ImageUploader class

    public class ImageUploader {

    private static String serverResponseMessage = "";
    private static int serverResponseCode = 0;
    private static ProgressDialog dialog;

    public static int uploadFile(final String sourceFileUri, final String serverFile, final Context context) {

        Debug.out("SourceFileUri: " + sourceFileUri);
        Debug.out("ServerFile: " + serverFile);
        Thread thread = new Thread() {
            @Override
            public void run() {
                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        dialog = new ProgressDialog(context);
                        dialog.setCancelable(false);
                        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                        dialog.setMessage("Uploading Image... Please wait!");
                        dialog.show();
                    }
                });
                String upLoadServerUri = serverFile;
                String fileName = sourceFileUri;
                HttpURLConnection conn = null;
                DataOutputStream dos = null;
                String lineEnd = "\r\n";
                String twoHyphens = "--";
                String boundary = "*****";
                int bytesRead, bytesAvailable, bufferSize;
                byte[] buffer;
                int maxBufferSize = 1 * 1024 * 1024;
                File sourceFile = new File(sourceFileUri);
                if (!sourceFile.isFile()) {
                    Log.e("uploadFile", "Source File Does not exist");
                }
                try { // open a URL connection to the Servlet
                    Debug.out("in the try");
                    FileInputStream fileInputStream = new FileInputStream(
                            sourceFile);
                    URL url = new URL(upLoadServerUri);
                    conn = (HttpURLConnection) url.openConnection(); // Open a
                                                                        // HTTP
                                                                        // connection
                                                                        // to
                                                                        // the
                                                                        // URL
                    conn.setDoInput(true); // Allow Inputs
                    conn.setDoOutput(true); // Allow Outputs
                    conn.setUseCaches(false); // Don't use a Cached Copy
                    conn.setRequestMethod("POST");
                    conn.setRequestProperty("Connection", "Keep-Alive");
                    conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                    conn.setRequestProperty("Content-Type",
                            "multipart/form-data;boundary=" + boundary);
                    conn.setRequestProperty("uploaded_file", fileName);
                    dos = new DataOutputStream(conn.getOutputStream());
                    Debug.out("Set Properties and Datastream");
                    dos.writeBytes(twoHyphens + boundary + lineEnd);
                    dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                            + fileName + "\"" + lineEnd);
                    dos.writeBytes(lineEnd);
                    Debug.out("Writes data");
                    bytesAvailable = fileInputStream.available(); // create a
                                                                    // buffer of
                                                                    // maximum
                                                                    // size

                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    buffer = new byte[bufferSize];
                    Debug.out("Buffer done");
                    // read file and write it into form...
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    Debug.out("Read Bytes");
                    while (bytesRead > 0) {
                        dos.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    }

                    // send multipart form data necesssary after file data...
                    dos.writeBytes(lineEnd);
                    dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                    Debug.out("After sendData");
                    // Responses from the server (code and message)
                    serverResponseCode = conn.getResponseCode();
                    serverResponseMessage = conn.getResponseMessage();
                    Debug.out("Server Response: " + serverResponseCode);
                    Log.i("uploadFile", "HTTP Response is : "
                            + serverResponseMessage + ": " + serverResponseCode);
                    Debug.out("HTTP Response is : " + serverResponseMessage
                            + ": " + serverResponseCode);
                    // close the streams //
                    fileInputStream.close();
                    dos.flush();
                    dos.close();
                }

                catch (MalformedURLException ex) {
                    ex.printStackTrace();
                    // Toast.makeText(UploadImageDemo.this,
                    // "MalformedURLException", Toast.LENGTH_SHORT).show();
                    Log.e("Upload file to server", "error: " + ex.getMessage(),
                            ex);
                } catch (Exception e) {
                    e.printStackTrace();
                    // Toast.makeText(UploadImageDemo.this, "Exception : " +
                    // e.getMessage(), Toast.LENGTH_SHORT).show();
                    Log.e("Upload file to server Exception",
                            "Exception : " + e.getMessage(), e);
                }

            }
        };
        thread.start();

        try {
            thread.join();      
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Debug.out("Message: " + serverResponseMessage.toString());
        return serverResponseCode;
    }
}
CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
Baklap4
  • 3,914
  • 2
  • 29
  • 56
  • 1
    why dont you write 2 methods to do this, one method to do the image upload and another to do the email. then do them both in the doInBackground? or even start another AsyncTask when the image upload ends? – tyczj Oct 21 '13 at 12:11
  • @Tarsem I want to show the progress dialog while uploading the image. So when the thread in ImageUploader is alive. – Baklap4 Oct 21 '13 at 12:13
  • show the progress dialog on preExecute and dismiss it on postExecute – Himanshu Joshi Oct 21 '13 at 12:14
  • @tyczj i've tried this aswell without success too bad. I've also tried making 2 async tasks, and call one asynctask while being in do-background, resulting in failures – Baklap4 Oct 21 '13 at 12:15
  • @Droid if i'm doing that, it won't show for just uploading the image, but also for sending the mail. Sending the mail ain't the problem. – Baklap4 Oct 21 '13 at 12:16
  • you call the second asynctask in the first asynctask's `onPostExecute` – tyczj Oct 21 '13 at 12:18

4 Answers4

3

As per your comment : "@Tarsem I want to show the progress dialog while uploading the image. So when the thread in ImageUploader is alive."

Try following apporach:

class imageupload extends AsyncTask<Void, Void, Void> {    
            Dialog dialog;    
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                dialog = ProgressDialog.show(context, "Uploading Image","Please Wait...");
            }    
            @Override
            protected Void doInBackground(Void... params) {
                // Upload Image HERE                    
                return null;
            }
            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                dialog.dismiss();                   
                // You can Call another AsynTask here (achieve sending email work here)             
             }
        }
Tarsem Singh
  • 14,139
  • 7
  • 51
  • 71
  • Hmmmm a bummer though, uploading an images takes like 1 minute, but the dialog only shows up for like 1 second... – Baklap4 Oct 21 '13 at 12:35
  • 2
    check that you dismiss it only in onPostExecute() this implementation shold work correctly – Ahmad Dwaik 'Warlock' Oct 21 '13 at 12:40
  • It is only called in onPostExecute(). And it works, as i can see the mail is send after the upload is finished. Yet the Dialog should be longer up, as the mail is send after like 40 seconds. But The Dialog is only up for 1 - 3 seconds. Uploading the images takes like 15 seconds. I guess it has something to do with the doInBackground() And the ui continuing to the next intent already? – Baklap4 Oct 21 '13 at 12:45
  • @Baklap4 as Worlock already commented make sure that you are not using `dialog.dismiss()` or `dialog.cancel()` in `doInBackground()` it should be used in `onPostExecute()` nothing is to do with `doInBackground()` regarding `dialog`.. other reason may be your email may be taking time to be sent... – Tarsem Singh Oct 21 '13 at 12:56
  • I'm only calling it in onPostExecute() – Baklap4 Oct 21 '13 at 12:58
  • When i'm pressing my button, so i can go to the next activity it starts the uploading of the image, and then sending the email. The email comes nice after uploading the image. But Somehow the UI-thread thinks, it's already done, while it's not o.O" – Baklap4 Oct 21 '13 at 13:00
  • @Baklap4 then its fine.. may be you are confused about your time calculations.. So i suggest you to debug your code properly.. good luck for debugging process... – Tarsem Singh Oct 21 '13 at 13:01
  • @Baklap4 Sorry its not clear to me, So what do you now actually want ? i.e. do you also want to show the `dialog` while sending email ? – Tarsem Singh Oct 21 '13 at 13:02
  • @Tarsem http://stackoverflow.com/questions/19495596/pressing-button-and-continuing-to-next-intent-progressdialog I've made a next question to clear out things :) – Baklap4 Oct 21 '13 at 13:16
2

You can show a progress dialog in pre execute, do both uploading the image and sending the email in doInBackground and hide the progress dialog in postExectue.

Uploading the image in preexecute is contrary to what the async task is for... If you perform the uploading in doInBackground there is no need for an extra thread. (That's what the AsyncTask handles for you)

Or you could upload the picture and then (in postexecute) start another task for sending the email although I don't see why you need to do that asynchronous? You could also just send an intent to send the email...?

jpm
  • 3,300
  • 1
  • 19
  • 29
2

Just use AsyncTask in following manner. In your main class make ProgressDialog's Object.

  private class UploadTask extends AsyncTask<Void, Void, Integer > {

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        pd = new ProgressDialog(MainActivity.this);
        pd.show();
    }
         protected Integer doInBackground(URL... urls) {
            if(isPhotoTaken()){
            ImageUploader.uploadFile(getPhotoPath(), "http://www.example.com/upload.php",Step4.this);              
        }
        return null;
         }


         protected void onPostExecute(Integer result) {
           pd.dismiss();
         }
     }
Karl-Johan Sjögren
  • 16,544
  • 7
  • 59
  • 68
Jitesh Dalsaniya
  • 1,917
  • 3
  • 20
  • 36
  • Thanks it works now! I've made a 2nd async task, and in onPostExecute i called the mailing AsyncTask – Baklap4 Oct 21 '13 at 12:28
  • Hmmmm a bummer though, uploading an images takes like 1 minute, but the dialog only shows up for like 1 second... – Baklap4 Oct 21 '13 at 12:35
  • Dialog show till your background task finished after that it is dismissed. – Jitesh Dalsaniya Oct 21 '13 at 12:36
  • hmmm The ImageUploader class, returns a statusCode, after the image is uploaded at the server, (the dialog should pop up and spin around while uploading and when statuscode = 200 it should dismiss) – Baklap4 Oct 21 '13 at 12:41
1

Async task comes with four methods onPreExecute() doInBackground() onPostExecute() and onUpdateProgress(), you just need to appropriately implement methods.

You show a progress in onPreExecute() do the upload and send email in doInBackground() update in onUpdateProgress() hide progress on onPostExecute().

EDIT

once you do it right you don't need thread anymore, because the main idea of AsyncTask is to make a separate thread/process and update the UI onPreExecute() onUpdateProgress() onPostExecute() runs on UI thread while doInBackground() fires a new thread, and can update UI by calling publishUpdate from within it, which in turn automatically call onUpdateProgress()

Ahmad Dwaik 'Warlock'
  • 5,953
  • 5
  • 34
  • 56