Android Upload Video To Server Using Volley is the topic of today.
You will learn to upload video to remote server (PHP-MySQL) using the volley library.
We will use multipart method of volley in this tutorial.
If you do not want to use volley then read how to upload video in android with http mime, client or apache.
For retrofit, visit android video upload using retrofit.
Check the Output
Below shows the working of this android upload video with volley example.
PHP related files
To insert the video into the web server, we need to write two PHP scripts.
Make a new PHP file and give it a name like config.php
Write down the below source lines in config.php
<?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"; } ?>
Above file will make the connection to the MySQL database.
Now create another file with the name uploadfile.php
Add the following source lines in uploadfile.php
<?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!") ); } } ?>
Above file is responsible to upload the video to the server. It will also add the entry into the MySQL database.
Now go to the android studio and make a new project.
Step 1. Gradle and Manifest changes
After making a new project, open the build.gradle(Module :app) file. Insert the below line in this file
implementation 'com.android.volley:volley:1.1.1'
Above line will fetch the volley library in to our android studio project. So that we can use various classes of volley library very easily.
Now open your AndroidManifest.xml file. Copy the below line in this file.
<uses-permission android:name="android.permission.INTERNET" />
This line will give access to internet in our project because without internet you can not upload video.
Internet permission is not much harmful to user privacy. So android have put this permission into the normal permission list and we do not need to ask for runtime permission for internet.
Step 2. Volley Multipart Class
Make a new JAVA class and give it a name VolleyMultipartRequest.java
Write down the following source lines in VolleyMultipartRequest.java
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 heart of volley multipart functionality.
Using the object of the above class, we can make http calls within few lines of code.
We will use this class in the main activity.
Step 3. Main Files for main purpose
All other tasks are done. Now we are just left with main files modification.
These two main files are activity_main.xml and MainActivity.java
In your activity_main.xml file, add the below source items
<?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 Video To upload with Volley" /> <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 Uploaded video with volley"/> <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>
Above file will create the main activity layout of our project.
This file contains one button and two text views. When the user clicks the button, system will redirect him to another screen.
From this screen, user can choose any video which he wants to upload to the server.
One text view has the static value and we will not change it’s text.
Another text view will get the URL to the recently uploaded video. When the user clicks on this text view, compiler will open this URL in the web browser.
Now in your MainActivity.java file, you should write down the below source code lines.
import android.content.Intent; import android.net.Uri; 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.Calendar; 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("video/*"); 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 = String.valueOf(Calendar.getInstance().getTimeInMillis()+".mp4"); Log.d("ooooooo",displayName); uploadPDF(displayName,uri); } 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(); } }
What is above code ?
Let us see what above code wants to say to the compiler and also to us.
First of all, consider the below code snippet
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 and second line is creating the object of Button and Text View class respectively.
Third line is the string variable with URL to the uploadfile.php
With this uploadfile.php file, we need to pass parameter so I have added a question mark “?” at the end of the URL.
Fourth line is making the object of the RequestQueue class, fifth line is making an array list with hash map.
Last one is the string variable with the Google URL as it’s value. We will update it’s value with the URL where our app will upload the video using volley.
Now look at the below 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 hit the above code when the user clicks the text view. It will open the URL to uploaded video in web browser.
See the following lines
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_GET_CONTENT); intent.setType("video/*"); startActivityForResult(intent,1); } });
Above is the button click scenario. Compiler will open one new intent which will present all the videos from android device.
User can select any video to upload it to the server.
When the user successfully selects the video, compiler will run the onActivityResult() method.
Below is the source code 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 = String.valueOf(Calendar.getInstance().getTimeInMillis()+".mp4"); Log.d("ooooooo",displayName); uploadPDF(displayName,uri); } super.onActivityResult(requestCode, resultCode, data); }
First of all, compiler will get the Uri of the video from data. Then it will make one string variable from this uri.
From this string variable, it will make one file object.
A string variable called “displayName” will contain the current time in milli second in string format.
Finally, execution of uploadPDF() method will take place.
Code writings for uploadPDF() method is as the following
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(); } }
Above method will make the http call to the uploadfile.php file.
When the compiler gets the JSON response from the server, it will call onResponse() method.
JSON response contains the URL to the uploaded video. Inside onResponse() method, compiler will fetch this URL and will set it as the value of the text view.
Now see the below line
params.put("filename", new DataPart(pdfname ,inputData));
Above line is the place, where we are placing the name and the data of the video.
Download Code For Android Upload Video To Server Using Volley
Click me to get the source code of volley video upload android from github