36

I'm sharing the solution to send an image , audio or a video file with parameters using HttpURLConnection. Parameters may be (plain string or JSON).

(Android Client to PHP Back end)

Scenario: Have to upload media files (audio , video and image with parameters).

Media files will be stored in a server folder and parameters to db.

I faced a problem that, image was uploaded successfully while parameters went missing.

Potential solution found

Choosing HttpURLConnection instead of Httpclient as recommend here

You may be wondering, Which client is best?

Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases.

For Gingerbread and better, HttpURLConnection is the best choice. Its simple API and small size makes it great fit for Android. Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.

Android Code:

public int uploadFile(final String sourceFileUri) {

    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()) {

        dialog.dismiss();

        Log.e("uploadFile", "Source File not exist :" + filepath);

        runOnUiThread(new Runnable() {
            public void run() {
                messageText.setText("Source File not exist :" + filepath);
            }
        });

        return 0;

    } else {
        try {
            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            URL url = new URL(upLoadServerUri);
            conn = (HttpURLConnection) url.openConnection();
            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());


            dos.writeBytes(twoHyphens + boundary + lineEnd);

//Adding Parameter name

            String name="amir";
            dos.writeBytes("Content-Disposition: form-data; name=\"name\"" + lineEnd); 
            //dos.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
            //dos.writeBytes("Content-Length: " + name.length() + lineEnd);
            dos.writeBytes(lineEnd);
            dos.writeBytes(name); // mobile_no is String variable
            dos.writeBytes(lineEnd);

            dos.writeBytes(twoHyphens + boundary + lineEnd);

//Adding Parameter phone
            String phone="9956565656";
            dos.writeBytes("Content-Disposition: form-data; name=\"phone\"" + lineEnd); 
            //dos.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
            //dos.writeBytes("Content-Length: " + name.length() + lineEnd);
            dos.writeBytes(lineEnd);
            dos.writeBytes(phone); // mobile_no is String variable
            dos.writeBytes(lineEnd);


            //Json_Encoder encode=new Json_Encoder();
            //call to encode method and assigning response data to variable 'data'
            //String data=encode.encod_to_json();
            //response of encoded data
            //System.out.println(data);


                //Adding Parameter filepath

            dos.writeBytes(twoHyphens + boundary + lineEnd);
            String filepath="http://192.168.1.110/echo/uploads"+fileName;

            dos.writeBytes("Content-Disposition: form-data; name=\"filepath\"" + lineEnd); 
            //dos.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
            //dos.writeBytes("Content-Length: " + name.length() + lineEnd);
            dos.writeBytes(lineEnd);
            dos.writeBytes(filepath); // mobile_no is String variable
            dos.writeBytes(lineEnd);


//Adding Parameter media file(audio,video and image)

            dos.writeBytes(twoHyphens + boundary + lineEnd);

            dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""+ fileName + "\"" + lineEnd);
            dos.writeBytes(lineEnd);
            // create a buffer of maximum size
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];
            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            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);


            serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();



            Log.i("uploadFile", "HTTP Response is : "+ serverResponseMessage + ": " + serverResponseCode);

            if (serverResponseCode == 200) {

                runOnUiThread(new Runnable() {
                    public void run() {
                         msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
                                + "c:/wamp/www/echo/uploads";
                        messageText.setText(msg);
                        Toast.makeText(MainActivity.this,
                                "File Upload Complete.", Toast.LENGTH_SHORT)
                                .show();
                    }
                });
            }

            // close the streams //
            fileInputStream.close();
            dos.flush();
            dos.close();

        } catch (MalformedURLException ex) {

            dialog.dismiss();
            ex.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText
                            .setText("MalformedURLException Exception : check script url.");
                    Toast.makeText(MainActivity.this,
                            "MalformedURLException", Toast.LENGTH_SHORT)
                            .show();
                }
            });

            Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
        } catch (final Exception e) {

            dialog.dismiss();
            e.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("Got Exception : "+e.toString());
                    Toast.makeText(MainActivity.this,
                            "Got Exception : see logcat ",
                            Toast.LENGTH_SHORT).show();
                }
            });
            Log.e("Upload file to server Exception",
                    "Exception : " + e.getMessage(), e);
        }
        dialog.dismiss();
        return serverResponseCode;
    }
}

Php code:

$file_path = "uploads/";

//receive parameters

  $name=$_POST['name'];
  $phone=$_POST['phone'];
  $filepath=$_POST['filepath'];


   //receive media files(image , audio and video)

   $file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
   if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) 
      {
      echo "Success";
      }

Hope this helps.

Any queries ask me.

alkber
  • 1,426
  • 2
  • 20
  • 26
Amir
  • 1,066
  • 1
  • 13
  • 26
  • are you able to get other variable with image or video ? please explain here – Mahesh Cheliya May 09 '15 at 07:36
  • For `conn` variable ,you have not invoked `connect` operation ,how can you expect to have response code? – zionpi Jun 16 '15 at 09:20
  • 26
    SO is a Q&A site. Please [edit] your post into a question that you leave here, and an answer that you post below. – Teepeemm Oct 29 '15 at 18:27
  • 1
    Actually devs uses OKHTTP/Retrofit to accomplish such tasks. Even Google doesn't use Apache client/HttpURLConnection but uses OKHTTP instead. Take a look at PlayMarket app to ensure. – Stan Mar 21 '16 at 10:09
  • HttpURLConnection is backed by okhttp (rather than Apache) in newer Android releases (4.4+). – szym Mar 26 '16 at 12:36

2 Answers2

1

You can use Retrofit for API call. Minimum support for Android is 2.3. Please check details.

Sanjay Kakadiya
  • 1,596
  • 1
  • 15
  • 32
0

You can make it more simpler! Try the following.

public static String uploadImage(Bitmap bitmap, String urlString) {
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap = Local.resize(bitmap, 512, 512);
        if(filename.toLowerCase().endsWith("jpg") || filename.toLowerCase().endsWith("jpeg"))
            bitmap.compress(Bitmap.CompressFormat.JPEG, 70, bos);
        if(filename.toLowerCase().endsWith("png"))
            bitmap.compress(Bitmap.CompressFormat.PNG, 70, bos);
        ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), filename);
        ContentBody body1 = new StringBody("something");
        ContentBody body2 = new StringBody("something");
        org.apache.http.entity.mime.MultipartEntity reqEntity = new org.apache.http.entity.mime.MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        reqEntity.addPart("image", contentPart);
        reqEntity.addPart("sample1", body1);
        reqEntity.addPart("sample2", body2);
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
        conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());
        OutputStream os = conn.getOutputStream();
        reqEntity.writeTo(conn.getOutputStream());
        os.close();
        conn.connect();
        if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            Log.d("UPLOAD", "HTTP 200 OK.");
            return readStream(conn.getInputStream());
            //This return returns the response from the upload.
        } else {
            Log.d("UPLOAD", "HTTP "+conn.getResponseCode()+" "+conn.getResponseMessage()+".");
            String stream =  readStream(conn.getInputStream());
            //Log.d("UPLOAD", "Response: "+stream);
            return stream;
        }
    } catch (Exception e) {
        Log.d("UPLOAD_ERROR", "Multipart POST Error: " + e + "(" + urlString + ")");
    }
    return null;
}
Sibidharan
  • 2,717
  • 2
  • 26
  • 54