Android Upload File To Server Programmatically PHP-MySQL Tutorial

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

Read on Android Upload File To Server Programmatically PHP-MySQL Tutorial.

I will guide you how to upload any file to php-MySQL server from android app.

We will use httpclient and multipart functionality to accomplish our goal.

A PHP script will help us to establish interaction between android app and remote server.

Final Output Video

See the following video which gives the output.

PHP Scripts

We need to create one PHP file which will help us to insert the file on to the remote server as well as MySQL database.

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"; 
  
   
   }
 
?>

Create another PHP file and its name should be uploadfile.php

Following is the code for 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!") );
        }
  }
?>

Now our PHP related work is complete. Now in your android studio, create a new project.

Step 1. Gradle Modifications

Every android studio have two types of gradle files.

First of all, open your build.gradle(Module :app) file, you need to add below lines in this file

  implementation group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1'
    implementation('org.apache.httpcomponents:httpmime:4.3') {
        exclude module: "httpclient"
    }
 implementation 'com.karumi:dexter:5.0.0'

First two lines are integrating some classes which will allow us to use httpclient and multipart in our android project.

Last line is for dexter library. This library will help us to simplify the process of asking the runtime permissions to the user.

After this, write the following lines in  build.gradle(Module :app) file

android{
        useLibrary  'org.apache.http.legacy'
    }
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }

So, final code for build.gradle(Module :app) file is as the below

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.parsaniahardik.upload_file_zerones"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    android{
        useLibrary  'org.apache.http.legacy'
    }
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1'
    implementation('org.apache.httpcomponents:httpmime:4.3') {
        exclude module: "httpclient"
    }
    implementation 'com.karumi:dexter:5.0.0'
}

Now it is time to update second gradle file which have the name like build.gradle(Project: Upload_file_Zerone). In this file name Upload_file_Zerone is the name of our android studio project.

Add the below line in this file

 maven { url 'https://jitpack.io' }

So last source code for build.gradle(Project: Upload_file_Zerone) is like the below

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Step 2. Making Permissions

In this project, we need to have three permissions from user.

Add the following source lines in AndroidManifest.xml file.

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

I have defined three permissions : Internet, Read external storage and Write external storage.

We also need to write runtime permissions code but I will cover them in MainActivity.java file.

Step 3. Necessary Interface

Create a new Interface and set the name as “AsyncTaskCompleteListener.java

Source snippet for AsyncTaskCompleteListener.java is as the below

public interface AsyncTaskCompleteListener {
    void onTaskCompleted(String response, int serviceCode);
}

We need to implement this interface in the main activity.

Step 4. Multipart related Class

Create a new JAVA class and set its name as MultiPartRequester.java

Write down the below lines in MultiPartRequester.java

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MIME;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.util.Map;

public class MultiPartRequester {

    private Map<String, String> map;
    private AsyncTaskCompleteListener mAsynclistener;
    private int serviceCode;
    private HttpClient httpclient;
    private Activity activity;
    private AsyncHttpRequest request;

    public MultiPartRequester(Activity activity, Map<String, String> map,
                              int serviceCode, AsyncTaskCompleteListener asyncTaskCompleteListener) {
        this.map = map;
        this.serviceCode = serviceCode;
        this.activity = activity;

        mAsynclistener = (AsyncTaskCompleteListener) asyncTaskCompleteListener;
        request = (AsyncHttpRequest) new AsyncHttpRequest().execute(map
                    .get("url"));

    }

    class AsyncHttpRequest extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            map.remove("url");
            try {

                HttpPost httppost = new HttpPost(urls[0]);
                httpclient = new DefaultHttpClient();

                HttpConnectionParams.setConnectionTimeout(
                        httpclient.getParams(), 600000);

                MultipartEntityBuilder builder = MultipartEntityBuilder
                        .create();

                for (String key : map.keySet()) {

                    if (key.equalsIgnoreCase("filename")) {
                        File f = new File(map.get(key));

                        builder.addBinaryBody(key, f,
                                ContentType.MULTIPART_FORM_DATA, f.getName());
                    } else {
                        builder.addTextBody(key, map.get(key), ContentType
                                .create("text/plain", MIME.DEFAULT_CHARSET));
                    }
                    Log.d("TAG", key + "---->" + map.get(key));
                    // System.out.println(key + "---->" + map.get(key));
                }

                httppost.setEntity(builder.build());

                ActivityManager manager = (ActivityManager) activity
                        .getSystemService(Context.ACTIVITY_SERVICE);

                if (manager.getMemoryClass() < 25) {
                    System.gc();
                }
                HttpResponse response = httpclient.execute(httppost);

                String responseBody = EntityUtils.toString(
                        response.getEntity(), "UTF-8");

                return responseBody;

            } catch (Exception e) {
                e.printStackTrace();
            } catch (OutOfMemoryError oume) {
                System.gc();

                Toast.makeText(
                        activity.getParent().getParent(),
                        "Run out of memory please colse the other background apps and try again!",
                        Toast.LENGTH_LONG).show();
            } finally {
                if (httpclient != null)
                    httpclient.getConnectionManager().shutdown();

            }
            return null;
        }

        @Override
        protected void onPostExecute(String response) {

            if (mAsynclistener != null) {
                mAsynclistener.onTaskCompleted(response, serviceCode);
            }
        }
    }
    private void showToast(String msg) {
        Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
    }

}

This multipart class will help us to make http calls using its objects.

We will use this class as a library, so do not change anything in this class.

Step 5. Main Activity Works

This is the final step in this tutorial.

There are two main files in this project. One is activity_main.xml and another is MainActivity.java

First, add the below code in activity_main.xml

<?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:background="#900ce2"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <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 the URL to Uploaded file"/>

    <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="#fff"
        android:textSize="25sp"
        android:text="URL to File"/>

    <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 Any file to Upload"
        />

</LinearLayout>

This layout file has one button and two text views.

One text view is static and we will not change it’s value. Another text view will hold the text as the URL of the uploaded file.

When the user clicks the button, system will open the file manager.

Now following is the code block for MainActivity.java file

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.DexterError;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.PermissionRequestErrorListener;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;

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

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity implements AsyncTaskCompleteListener{

    private Button btn;
    private TextView tv;
    private String url = "https://www.google.com";
    private static final int BUFFER_SIZE = 1024 * 2;
    private static final String IMAGE_DIRECTORY = "/demonuts_files";
    private final int GALLERY = 1;
    private ArrayList<HashMap<String, String>> arraylist;

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

        requestMultiplePermissions();

        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("file/*");
                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 path = getFilePathFromURI(MainActivity.this,uri);
            Log.d("ioooo",path);

            uploadPDFfile(path);

        }

        super.onActivityResult(requestCode, resultCode, data);

    }

    private void uploadPDFfile(String path) {

        HashMap<String, String> map = new HashMap<String, String>();
        map.put("url", "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php");
        map.put("filename", path);
        new MultiPartRequester(this, map, GALLERY, this);

    }

    @Override
    public void onTaskCompleted(String response, int serviceCode) {

        Log.d("res", response);
        switch (serviceCode) {

            case GALLERY:
                try {

                    JSONObject jsonObject = new JSONObject(response);
                    jsonObject.toString().replace("\\\\","");
                    if (jsonObject.getString("status").equals("true")) {

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

    public static String getFilePathFromURI(Context context, Uri contentUri) {
        //copy file and send new file path
        String fileName = getFileName(contentUri);
        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
        // have the object build the directory structure, if needed.
        if (!wallpaperDirectory.exists()) {
            wallpaperDirectory.mkdirs();
        }
        if (!TextUtils.isEmpty(fileName)) {
            File copyFile = new File(wallpaperDirectory + File.separator + Calendar.getInstance()
                    .getTimeInMillis()+".txt");
            // create folder if not exists

            copy(context, contentUri, copyFile);
            return copyFile.getAbsolutePath();
        }
        return null;
    }

    public static String getFileName(Uri uri) {
        if (uri == null) return null;
        String fileName = null;
        String path = uri.getPath();
        int cut = path.lastIndexOf('/');
        if (cut != -1) {
            fileName = path.substring(cut + 1);
        }
        return fileName;
    }

    public static void copy(Context context, Uri srcUri, File dstFile) {
        try {
            InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
            if (inputStream == null) return;
            OutputStream outputStream = new FileOutputStream(dstFile);
            copystream(inputStream, outputStream);
            inputStream.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int copystream(InputStream input, OutputStream output) throws Exception, IOException {
        byte[] buffer = new byte[BUFFER_SIZE];

        BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
        BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
        int count = 0, n = 0;
        try {
            while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
                out.write(buffer, 0, n);
                count += n;
            }
            out.flush();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                Log.e(e.getMessage(), String.valueOf(e));
            }
            try {
                in.close();
            } catch (IOException e) {
                Log.e(e.getMessage(), String.valueOf(e));
            }
        }
        return count;
    }


    private void  requestMultiplePermissions(){
        Dexter.withActivity(this)
                .withPermissions(

                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                .withListener(new MultiplePermissionsListener() {
                    @Override
                    public void onPermissionsChecked(MultiplePermissionsReport report) {
                        // check if all permissions are granted
                        if (report.areAllPermissionsGranted()) {
                            Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show();
                        }

                        // check for permanent denial of any permission
                        if (report.isAnyPermissionPermanentlyDenied()) {
                            // show alert dialog navigating to Settings

                        }
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                        token.continuePermissionRequest();
                    }
                }).
                withErrorListener(new PermissionRequestErrorListener() {
                    @Override
                    public void onError(DexterError error) {
                        Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show();
                    }
                })
                .onSameThread()
                .check();
    }

}

Reading above code

First of all, see the below source

 private Button btn;
    private TextView tv;
    private String url = "https://www.google.com";
    private static final int BUFFER_SIZE = 1024 * 2;
    private static final String IMAGE_DIRECTORY = "/demonuts_files";
    private final int GALLERY = 1;
    private ArrayList<HashMap<String, String>> arraylist;

First line is making an object of button class. Second one is for text view class.

Third line is making one string variable and its value is google URL.

Fourth one making an integer variable which defines buffer size.

Fifth line is string variable which holds the “directory” where we will save the file.

Sixth line is integer variable and last one is making one araylist of Hashmaps.

Now read the onCreate() method. It holds a method requestMultiplePermissions()

Source lines for requestMultiplePermissions() method is as the following

  private void  requestMultiplePermissions(){
        Dexter.withActivity(this)
                .withPermissions(

                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                .withListener(new MultiplePermissionsListener() {
                    @Override
                    public void onPermissionsChecked(MultiplePermissionsReport report) {
                        // check if all permissions are granted
                        if (report.areAllPermissionsGranted()) {
                            Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show();
                        }

                        // check for permanent denial of any permission
                        if (report.isAnyPermissionPermanentlyDenied()) {
                            // show alert dialog navigating to Settings

                        }
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                        token.continuePermissionRequest();
                    }
                }).
                withErrorListener(new PermissionRequestErrorListener() {
                    @Override
                    public void onError(DexterError error) {
                        Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show();
                    }
                })
                .onSameThread()
                .check();
    }

This method is taking care of runtime permissions stuff.

We will ask for two permissions : Read and write external storage.

Method will use dexter library to implement professional behavior regarding runtime permission environment.

Now consider the following source snippet

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

System will run the above code when the user clicks the button.

It will create one intent which will led the user to the new screen.

New screen will open all the files of android device and user can select any one to upload it to the server.

Now see the below source lines

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

When user clicks the text view, compiler will open the URL in web browser to which file is uploaded.

After selecting the file from file manager, compiler will run the onActivityResult() method.

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 path = getFilePathFromURI(MainActivity.this,uri);
            Log.d("ioooo",path);

            uploadPDFfile(path);

        }

        super.onActivityResult(requestCode, resultCode, data);

    }

Compiler will first get the Uri of the selected file.

Then it will store the file using getFilePathFromURI() method. This method will return the path to the saved file.

Using this path, compiler will run the uploadPDFfile() function.

Below is the source lines for uploadPDFfile() function.

 private void uploadPDFfile(String path) {

        HashMap<String, String> map = new HashMap<String, String>();
        map.put("url", "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php");
        map.put("filename", path);
        new MultiPartRequester(this, map, GALLERY, this);

    }

Here, compiler will create one Hashmap with string as a key and value.

It will add url in first map and a path to the file in the second map.

Then it will make the http call using the MultipartRequester class.

After successful http call, compiler will run the onTaskCompleted() method.

Following is the code snippet for onTaskCompleted() method.

@Override
    public void onTaskCompleted(String response, int serviceCode) {

        Log.d("res", response);
        switch (serviceCode) {

            case GALLERY:
                try {

                    JSONObject jsonObject = new JSONObject(response);
                    jsonObject.toString().replace("\\\\","");
                    if (jsonObject.getString("status").equals("true")) {

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

In this method, compiler will have a JSON response in the string format.

It will parse this JSON response and will get the URL where the uploaded file resides.

Then it will set this URL as the value of the text view.

Download Source Code For android upload file

https://github.com/demonuts/android-upload-file.