Upload PDF File To Server In Android Using Volley

upload pdf file to server in android using volley, upload pdf file to server in android using retrofit, Android Upload PDF File To Server Example Tutorial, android upload video, android upload video to server using volley, android upload video to server using retrofit, android upload file

Learn how to Upload PDF File To Server In Android Using Volley.

When you want to upload PDF file to server using volley in android studio, you need to use Multipart mechanism.

We will use Volley library to avoid some common problems while making http calls to the server.

See PDF

Below video shows you the result of this tutorial.

PHP web services

We need two php files in this example. One is about database configuration and other one for upload of PDF.

Make a new file named uploadfile.php and add the below code

<?php
 if($_SERVER['REQUEST_METHOD']=='POST'){
  	// echo $_SERVER["DOCUMENT_ROOT"];  // /home1/demonuts/public_html
	//including the database connection file
  	include_once("config.php");
  	  	
  	//$_FILES['image']['name']   give original name from parameter where 'image' == parametername eg. city.jpg
  	//$_FILES['image']['tmp_name']  temporary system generated name
  
        $originalImgName= $_FILES['filename']['name'];
        $tempName= $_FILES['filename']['tmp_name'];
        $folder="uploadedFiles/";
        $url = "https://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName; //update path as per your directory structure 
        
        if(move_uploaded_file($tempName,$folder.$originalImgName)){
                $query = "INSERT INTO upload_image_video (pathToFile) VALUES ('$url')";
                if(mysqli_query($con,$query)){
                
                	 $query= "SELECT * FROM upload_image_video WHERE pathToFile='$url'";
	                 $result= mysqli_query($con, $query);
	                 $emparray = array();
	                     if(mysqli_num_rows($result) > 0){  
	                     while ($row = mysqli_fetch_assoc($result)) {
                                     $emparray[] = $row;
                                   }
                                   echo json_encode(array( "status" => "true","message" => "Successfully file added!" , "data" => $emparray) );
                                   
	                     }else{
	                     		echo json_encode(array( "status" => "false","message" => "Failed!") );
	                     }
			   
                }else{
                	echo json_encode(array( "status" => "false","message" => "Failed!") );
                }
        	//echo "moved to ".$url;
        }else{
        	echo json_encode(array( "status" => "false","message" => "Failed!") );
        }
  }
?>

Now create another script and give it a name like config.php

Source code for config.php is as the following

<?php
$host="localhost";
$user="your username";
$password="your password";
$db = "your db name";
 
$con = mysqli_connect($host,$user,$password,$db);
 
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }else{  //echo "Connect"; 
  
   
   }
 
?>

Now let us go to android studio. Create a new project with Empty activity as a default page.

Step 1. Manifest and gradle writings

To add internet permission in your app, write down the below line in AndroidManifest.xml file

 <uses-permission android:name="android.permission.INTERNET" />

This internet permission is normal permission for user security therefore we do not need to ask for runtime permissions.

Now in your build.gradle(Module: app) file, you need to copy following line

 implementation 'com.android.volley:volley:1.1.1'

Above line will integrate volley classes in our android studio project. We will able to use them seamlessly because of this line.

Step 2. Volley Multipart Class

Now create a new JAVA class and give it a name like VolleyMultipartRequest.java

Following is the code snippet for VolleyMultipartRequest.java file.

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

public class VolleyMultipartRequest extends Request<NetworkResponse> {

    private final String twoHyphens = "--";
    private final String lineEnd = "\r\n";
    private final String boundary = "apiclient-" + System.currentTimeMillis();

    private Response.Listener<NetworkResponse> mListener;
    private Response.ErrorListener mErrorListener;
    private Map<String, String> mHeaders;


    public VolleyMultipartRequest(int method, String url,
                                  Response.Listener<NetworkResponse> listener,
                                  Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return (mHeaders != null) ? mHeaders : super.getHeaders();
    }

    @Override
    public String getBodyContentType() {
        return "multipart/form-data;boundary=" + boundary;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);

        try {
            // populate text payload
            Map<String, String> params = getParams();
            if (params != null && params.size() > 0) {
                textParse(dos, params, getParamsEncoding());
            }

            // populate data byte payload
            Map<String, DataPart> data = getByteData();
            if (data != null && data.size() > 0) {
                dataParse(dos, data);
            }

            // close multipart form data after text and file data
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Custom method handle data payload.
     *
     * @return Map data part label with data byte
     * @throws AuthFailureError
     */
    protected Map<String, DataPart> getByteData() throws AuthFailureError {
        return null;
    }

    @Override
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
        try {
            return Response.success(
                    response,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (Exception e) {
            return Response.error(new ParseError(e));
        }
    }

    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

    @Override
    public void deliverError(VolleyError error) {
        mErrorListener.onErrorResponse(error);
    }

    /**
     * Parse string map into data output stream by key and value.
     *
     * @param dataOutputStream data output stream handle string parsing
     * @param params           string inputs collection
     * @param encoding         encode the inputs, default UTF-8
     * @throws IOException
     */
    private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
            }
        } catch (UnsupportedEncodingException uee) {
            throw new RuntimeException("Encoding not supported: " + encoding, uee);
        }
    }

    /**
     * Parse data into data output stream.
     *
     * @param dataOutputStream data output stream handle file attachment
     * @param data             loop through data
     * @throws IOException
     */
    private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
        for (Map.Entry<String, DataPart> entry : data.entrySet()) {
            buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
        }
    }

    /**
     * Write string data into header and data output stream.
     *
     * @param dataOutputStream data output stream handle string parsing
     * @param parameterName    name of input
     * @param parameterValue   value of input
     * @throws IOException
     */
    private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
        dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
        dataOutputStream.writeBytes(lineEnd);
        dataOutputStream.writeBytes(parameterValue + lineEnd);
    }

    /**
     * Write data file into header and data output stream.
     *
     * @param dataOutputStream data output stream handle data parsing
     * @param dataFile         data byte as DataPart from collection
     * @param inputName        name of data input
     * @throws IOException
     */
    private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
        dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
                inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
        if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
            dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
        }
        dataOutputStream.writeBytes(lineEnd);

        ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
        int bytesAvailable = fileInputStream.available();

        int maxBufferSize = 1024 * 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);

        while (bytesRead > 0) {
            dataOutputStream.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        dataOutputStream.writeBytes(lineEnd);
    }

    class DataPart {
        private String fileName;
        private byte[] content;
        private String type;

        public DataPart() {
        }

        DataPart(String name, byte[] data) {
            fileName = name;
            content = data;
        }

        String getFileName() {
            return fileName;
        }

        byte[] getContent() {
            return content;
        }

        String getType() {
            return type;
        }

    }
}

Above class is the static one and we do not need to change anything in this.

We will directly use the object of this class to make http calls with volley library.

Step 3. Final Main Changes

Now our last task is to add some lines in main files. You should have two files when you created a new project.

One is activity_main.xml and another is MainActivity.java

In your activity_main.xml file, add the below code structure

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:text="Select PDF"
       />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:textColor="#000"
        android:textSize="25sp"
        android:text="Below is URL to PDF"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:textColor="#000"
        android:textSize="25sp"
        android:text="URL to PDF"/>

</LinearLayout>
  • This XML file contains two text views and one button.
  • When the user clicks the button, he will show a file manager app. From here, he can select a pdf file which he wants to upload to the server.
  • One text view is static and we will not change it’s value.
  • Another text view will contain the URL to the uploaded PDF file.
  • When the user clicks on this URL, we will open up that URL in the browser and in the browser, user can see the uploaded image using volley.

Now in your MainActivity.java file, you need to write the below source lines.

import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    private Button btn;
    private TextView tv;
    private String upload_URL = "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php?";
    private RequestQueue rQueue;
    private ArrayList<HashMap<String, String>> arraylist;
    String url = "https://www.google.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = findViewById(R.id.btn);
        tv = findViewById(R.id.tv);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_GET_CONTENT);
                intent.setType("application/pdf");
                startActivityForResult(intent,1);
            }
        });

        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(browserIntent);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            // Get the Uri of the selected file
            Uri uri = data.getData();
            String uriString = uri.toString();
            File myFile = new File(uriString);
            String path = myFile.getAbsolutePath();
            String displayName = null;

            if (uriString.startsWith("content://")) {
                Cursor cursor = null;
                try {
                    cursor = this.getContentResolver().query(uri, null, null, null, null);
                    if (cursor != null && cursor.moveToFirst()) {
                        displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                        Log.d("nameeeee>>>>  ",displayName);

                        uploadPDF(displayName,uri);
                    }
                } finally {
                    cursor.close();
                }
            } else if (uriString.startsWith("file://")) {
                displayName = myFile.getName();
                Log.d("nameeeee>>>>  ",displayName);
            }
        }

        super.onActivityResult(requestCode, resultCode, data);

   }

   private void uploadPDF(final String pdfname, Uri pdffile){

       InputStream iStream = null;
       try {

           iStream = getContentResolver().openInputStream(pdffile);
           final byte[] inputData = getBytes(iStream);

           VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, upload_URL,
                   new Response.Listener<NetworkResponse>() {
                       @Override
                       public void onResponse(NetworkResponse response) {
                           Log.d("ressssssoo",new String(response.data));
                           rQueue.getCache().clear();
                           try {
                               JSONObject jsonObject = new JSONObject(new String(response.data));
                               Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show();

                               jsonObject.toString().replace("\\\\","");

                               if (jsonObject.getString("status").equals("true")) {
                                    Log.d("come::: >>>  ","yessssss");
                                   arraylist = new ArrayList<HashMap<String, String>>();
                                   JSONArray dataArray = jsonObject.getJSONArray("data");


                                   for (int i = 0; i < dataArray.length(); i++) {
                                       JSONObject dataobj = dataArray.getJSONObject(i);
                                       url = dataobj.optString("pathToFile");
                                       tv.setText(url);
                                   }


                               }
                           } catch (JSONException e) {
                               e.printStackTrace();
                           }
                       }
                   },
                   new Response.ErrorListener() {
                       @Override
                       public void onErrorResponse(VolleyError error) {
                           Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
                       }
                   }) {

               /*
                * If you want to add more parameters with the image
                * you can do it here
                * here we have only one parameter with the image
                * which is tags
                * */
               @Override
               protected Map<String, String> getParams() throws AuthFailureError {
                   Map<String, String> params = new HashMap<>();
                   // params.put("tags", "ccccc");  add string parameters
                   return params;
               }

               /*
                *pass files using below method
                * */
               @Override
               protected Map<String, DataPart> getByteData() {
                   Map<String, DataPart> params = new HashMap<>();

                   params.put("filename", new DataPart(pdfname ,inputData));
                   return params;
               }
           };


           volleyMultipartRequest.setRetryPolicy(new DefaultRetryPolicy(
                   0,
                   DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                   DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
           rQueue = Volley.newRequestQueue(MainActivity.this);
           rQueue.add(volleyMultipartRequest);



       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }


   }

    public byte[] getBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];

        int len = 0;
        while ((len = inputStream.read(buffer)) != -1) {
            byteBuffer.write(buffer, 0, len);
        }
        return byteBuffer.toByteArray();
    }

}

See Code Step by Step

First of all, read the below code,

 private Button btn;
 private TextView tv;
 private String upload_URL = "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php?";
 private RequestQueue rQueue;
 private ArrayList<HashMap<String, String>> arraylist;
 String url = "https://www.google.com";
  • First line is making an object of the button class. Second is creating the text view object.
  • Third line making one string variable. This variable is containing the URL to the web service. This web service will upload the PDf file to server and also to MySQL database.
  • At the end of the URL, I have added a question mark ? sign, because in the parameter of this web service, we will pass the name of PDF file in string format and PDF file itself in byte array format.
  • Fourth line is the object of RequestQueue class. Fifth line is making one array list with the hash map as a child.

Last line is simply a URL to the google.

Now consider below code

  btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_GET_CONTENT);
                intent.setType("application/pdf");
                startActivityForResult(intent,1);
            }
        });
  • When the user clicks the button, compiler will execute above code.
  • Compiler will open file manager and user can select any PDF file from here.

Now look at the following code

  tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(browserIntent);
            }
        });
  • Compiler will follow above code on the click event of text view. It will open the url in the browser. This url is the address to the uploaded PDF file.
  • So user will see the uploaded PDF file which will be loaded from the server. See the output video for better understandings.

Below is the source for onActivityResult() method.

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            // Get the Uri of the selected file
            Uri uri = data.getData();
            String uriString = uri.toString();
            File myFile = new File(uriString);
            String path = myFile.getAbsolutePath();
            String displayName = null;

            if (uriString.startsWith("content://")) {
                Cursor cursor = null;
                try {
                    cursor = this.getContentResolver().query(uri, null, null, null, null);
                    if (cursor != null && cursor.moveToFirst()) {
                        displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                        Log.d("nameeeee>>>>  ",displayName);

                        uploadPDF(displayName,uri);
                    }
                } finally {
                    cursor.close();
                }
            } else if (uriString.startsWith("file://")) {
                displayName = myFile.getName();
                Log.d("nameeeee>>>>  ",displayName);
            }
        }

        super.onActivityResult(requestCode, resultCode, data);

   }
  • When user selects the PDF file, compiler will run the above method.
  • First of all, it will fetch the URI of the selected PDF file. Then it will create one file from this URI.
  • Then some coding lines will give us the name of the PDF file.
  • A string variable displayName will contain the name of PDF file.

After this, compiler will call the uploadPDF() method. Source code for uploadPDF() method is as the below

private void uploadPDF(final String pdfname, Uri pdffile){

       InputStream iStream = null;
       try {

           iStream = getContentResolver().openInputStream(pdffile);
           final byte[] inputData = getBytes(iStream);

           VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, upload_URL,
                   new Response.Listener<NetworkResponse>() {
                       @Override
                       public void onResponse(NetworkResponse response) {
                           Log.d("ressssssoo",new String(response.data));
                           rQueue.getCache().clear();
                           try {
                               JSONObject jsonObject = new JSONObject(new String(response.data));
                               Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show();

                               jsonObject.toString().replace("\\\\","");

                               if (jsonObject.getString("status").equals("true")) {
                                    Log.d("come::: >>>  ","yessssss");
                                   arraylist = new ArrayList<HashMap<String, String>>();
                                   JSONArray dataArray = jsonObject.getJSONArray("data");


                                   for (int i = 0; i < dataArray.length(); i++) {
                                       JSONObject dataobj = dataArray.getJSONObject(i);
                                       url = dataobj.optString("pathToFile");
                                       tv.setText(url);
                                   }


                               }
                           } catch (JSONException e) {
                               e.printStackTrace();
                           }
                       }
                   },
                   new Response.ErrorListener() {
                       @Override
                       public void onErrorResponse(VolleyError error) {
                           Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
                       }
                   }) {

               /*
                * If you want to add more parameters with the image
                * you can do it here
                * here we have only one parameter with the image
                * which is tags
                * */
               @Override
               protected Map<String, String> getParams() throws AuthFailureError {
                   Map<String, String> params = new HashMap<>();
                   // params.put("tags", "ccccc");  add string parameters
                   return params;
               }

               /*
                *pass files using below method
                * */
               @Override
               protected Map<String, DataPart> getByteData() {
                   Map<String, DataPart> params = new HashMap<>();

                   params.put("filename", new DataPart(pdfname ,inputData));
                   return params;
               }
           };


           volleyMultipartRequest.setRetryPolicy(new DefaultRetryPolicy(
                   0,
                   DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                   DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
           rQueue = Volley.newRequestQueue(MainActivity.this);
           rQueue.add(volleyMultipartRequest);



       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }


   }
  • This method has two parameters. First is the name of file and another is PDF file in URI form.
  • First, compiler will convert this URI into Input Stream and from Input Stream, it will convert it into byte array.
  • A byte array variable inputData will contain PDF file in byte array format.
  • So compiler will make http call using name of the PDF file and byte array of PDF file.
  • When the compiler got the JSON response from server it will run onResponse() method.
  • Inside onResponse() method, compiler will get the JSON response in string format.
  • Then it will parse this Json response and will get the URL the uploaded PDF file. It will set this URL as a text of the text view.

Download Source Code for upload pdf file to server in android using volley

Download Code for Android How to upload PD File