Android Upload File to Server

Android Upload file to server using PHP, MySQL

In this Android Upload File to Server tutorial, we are going to discuss about how to select a file in android and upload it to the server using New Android Studio. Using the following code, we can successfully upload images, videos, documents, zip files, etc.. to the server. The code is tested for files upto 10MB of size.

android upload file to server featured logo

Note:

The link to download the complete code for the following tutorial is given at the bottom of this article.

Android Upload file to Server:

For this tutorial, I have created a New Project Named UploadFileToServer. Now let us first declare the permissions required in our Android Manifest file.

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

The above permissions are required to access Internet and to Read Android External Storage files.

I have written the following code in activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="@color/colorAccent"
    tools:context="com.coderefer.uploadfiletoserver.MainActivity">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="18sp"
        android:id="@+id/tvHeading"
        android:text="Touch the icon below to upload file to server"
        android:textColor="#fff"
        android:textStyle="bold"/>
    <ImageView
        android:id="@+id/ivAttachment"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/attach_icon"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"/>

    <TextView
        android:id="@+id/tv_file_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:layout_below="@+id/ivAttachment"
        android:layout_centerHorizontal="true"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/b_upload"
        android:text="Upload"
        android:textStyle="bold"
        android:textSize="20sp"
        android:layout_alignParentBottom="true"
        android:gravity="center"
        android:textColor="#fff"
        android:background="#039be5"/>

</RelativeLayout>
[widget id=”text-3″]

Now create a java class named FilePath.java and add the following code to it:

package com.coderefer.uploadfiletoserver;

/**
 * Created by vamsi on 24-Feb-16.
 */

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class FilePath {

    /**
     * Method for return file path of Gallery image/ Document / Video / Audio
     *
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    public static String getPath(final Context context, final Uri uri) {

        // check here to KITKAT or new version
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/"
                            + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] { split[1] };

                return getDataColumn(context, contentUri, selection,
                        selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context
     *            The context.
     * @param uri
     *            The Uri to query.
     * @param selection
     *            (Optional) Filter used in the query.
     * @param selectionArgs
     *            (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri,
                                       String selection, String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = { column };

        try {
            cursor = context.getContentResolver().query(uri, projection,
                    selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri
                .getAuthority());
    }
}

The above class is used to return the file path of the selected document/ video / audio etc..

Now we declare the MainActivity.java as follows:

package com.coderefer.uploadfiletoserver;

import android.app.Activity;
import android.app.ProgressDialog;
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.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static final int PICK_FILE_REQUEST = 1;
    private static final String TAG = MainActivity.class.getSimpleName();
    private String selectedFilePath;
    private String SERVER_URL = "http://coderefer.com/extras/UploadToServer.php";
    ImageView ivAttachment;
    Button bUpload;
    TextView tvFileName;
    ProgressDialog dialog;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivAttachment = (ImageView) findViewById(R.id.ivAttachment);
        bUpload = (Button) findViewById(R.id.b_upload);
        tvFileName = (TextView) findViewById(R.id.tv_file_name);
        ivAttachment.setOnClickListener(this);
        bUpload.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v== ivAttachment){

            //on attachment icon click
            showFileChooser();
        }
        if(v== bUpload){

            //on upload button Click
            if(selectedFilePath != null){
                dialog = ProgressDialog.show(MainActivity.this,"","Uploading File...",true);

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //creating new thread to handle Http Operations
                        uploadFile(selectedFilePath);
                    }
                }).start();
            }else{
                Toast.makeText(MainActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show();
            }

        }
    }

    private void showFileChooser() {
        Intent intent = new Intent();
        //sets the select file to all types of files
        intent.setType("*/*");
        //allows to select data and return it
        intent.setAction(Intent.ACTION_GET_CONTENT);
        //starts new activity to select file and return data
        startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == Activity.RESULT_OK){
            if(requestCode == PICK_FILE_REQUEST){
                if(data == null){
                    //no data present
                    return;
                }


                Uri selectedFileUri = data.getData();
                selectedFilePath = FilePath.getPath(this,selectedFileUri);
                Log.i(TAG,"Selected File Path:" + selectedFilePath);

                if(selectedFilePath != null && !selectedFilePath.equals("")){
                    tvFileName.setText(selectedFilePath);
                }else{
                    Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

//android upload file to server
    public int uploadFile(final String selectedFilePath){

        int serverResponseCode = 0;

        HttpURLConnection connection;
        DataOutputStream dataOutputStream;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";


        int bytesRead,bytesAvailable,bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        File selectedFile = new File(selectedFilePath);


        String[] parts = selectedFilePath.split("/");
        final String fileName = parts[parts.length-1];

        if (!selectedFile.isFile()){
            dialog.dismiss();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvFileName.setText("Source File Doesn't Exist: " + selectedFilePath);
                }
            });
            return 0;
        }else{
            try{
                FileInputStream fileInputStream = new FileInputStream(selectedFile);
                URL url = new URL(SERVER_URL);
                connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);//Allow Inputs
                connection.setDoOutput(true);//Allow Outputs
                connection.setUseCaches(false);//Don't use a cached Copy
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("ENCTYPE", "multipart/form-data");
                connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                connection.setRequestProperty("uploaded_file",selectedFilePath);

                //creating new dataoutputstream
                dataOutputStream = new DataOutputStream(connection.getOutputStream());

                //writing bytes to data outputstream
                dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
                dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                        + selectedFilePath + "\"" + lineEnd);

                dataOutputStream.writeBytes(lineEnd);

                //returns no. of bytes present in fileInputStream
                bytesAvailable = fileInputStream.available();
                //selecting the buffer size as minimum of available bytes or 1 MB
                bufferSize = Math.min(bytesAvailable,maxBufferSize);
                //setting the buffer as byte array of size of bufferSize
                buffer = new byte[bufferSize];

                //reads bytes from FileInputStream(from 0th index of buffer to buffersize)
                bytesRead = fileInputStream.read(buffer,0,bufferSize);

                //loop repeats till bytesRead = -1, i.e., no bytes are left to read
                while (bytesRead > 0){
                    //write the bytes read from inputstream
                    dataOutputStream.write(buffer,0,bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable,maxBufferSize);
                    bytesRead = fileInputStream.read(buffer,0,bufferSize);
                }

                dataOutputStream.writeBytes(lineEnd);
                dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

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

                Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);

                //response code of 200 indicates the server status OK
                if(serverResponseCode == 200){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tvFileName.setText("File Upload completed.\n\n You can see the uploaded file here: \n\n" + "http://coderefer.com/extras/uploads/"+ fileName);
                        }
                    });
                }

                //closing the input and output streams 
                fileInputStream.close();
                dataOutputStream.flush();
                dataOutputStream.close();



            } catch (FileNotFoundException e) {
                e.printStackTrace();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,"File Not Found",Toast.LENGTH_SHORT).show();
                    }
                });
            } catch (MalformedURLException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "URL error!", Toast.LENGTH_SHORT).show();
                
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "Cannot Read/Write File!", Toast.LENGTH_SHORT).show();
            }
            dialog.dismiss();
            return serverResponseCode;
        }

    }
}
[widget id=”text-3″]

The above code is commented wherever it is necessary. In this MainActivity.java, we wired up the attachment icon, Textview and Upload button and coded them such that when the icon is clicked, we can select the required file so that the textview gets updated with the path of the selected file. When we click on Upload button, a ProgressBar appears indicating that the file is being uploaded to the server. After the upload, the ProgressBar disappears and the textview gets updated detailing where the file has been uploaded in the server.

Server Side PHP Script for Android Upload File to Server:

Now create a serverside PHP Script that allow Android Upload file to server. Here I named it UploadToServer.php and added the following code:

<?php
  
    $file_path = "uploads/";
     
    $file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
    if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path) ){
        echo "success";
    } else{
        echo "fail";
    }
 ?>

I have placed the above file in Coderefer.com/extras folder. The above code creates a new folder named uploads and places the files being uploaded to uploads folder.

The complete code to demonstrate Android Upload file to server can be cloned/downloaded from the github repo below:

Click here to download

Note: In order for the above code to work, you need to  place php file (given in the project) in your own server/testing environment.

Comments 59

  1. Thank you so much sir it was very helpful for me.
    sir i hv an query that
    what should i do if i want to rename the file to the particular string. and then the file is upload with the new name on the server..

  2. This tutorial was very useful.
    I have one question i need to ask you.
    I want to know how to download file to Android.
    plz answer me

    1. Hello Hansol. i want to ask do you have a working code of uploading file on server?
      i would be really thankful to you if you provide me with the source code
      regards.

  3. Is there a reason why the php portion of this wouldn’t work or be able to find anything? I’m able to successfully go through the whole process, access the file, get it’s path and perform the connection and receive a response by asking for the getInputStream() but my server can’t find anything using your code for php. I left the variable names the same and literally copied and pasted the php code exactly.. I just can’t figure out why it thinks nothing is there. If I try to var_dump($_FILES[‘uploaded_file’]) it says that it’s null.

  4. Hello, Can you make this work with mysql? Like uploading file to a server and inserting the URL to the mysql with the uploader username?

  5. Pingback: Android Templates and advance concepts – vaidehipjoshi25

  6. thanks for the tutorial but i get this error application introuvable pour exécuter cette action any idea??

  7. Thanks for the tutorial.
    I downloaded your project from site and ran it on my phone. After opening the file chooser any type of the file was not getting selected(like all files appeared faded which could not be clicked). Please give a solution to my problem.

        1. Thank u so much.Here if I select file from sd card,it is showing “Cannot upload file to server”.Is it possible to upload file from sd card using same code or any changes are there?

  8. Great article, much appreciated!

    Some help for previous commenters and future readers –

    Issue: Grayed-out files in file chooser.
    Possible solution: Modify line 78 of MainActivity.java. I changed it to “intent.setType(“image/jpeg”) to better suite my use case.

    Issue: HTTP 200 (OK) but uploaded file nowhere to be found when using your own server.

    Possible solution: Fix your target folder permissions.

  9. nice post..
    am new to android and used your codes but when i click attachment icon i get a popup which says” No apps can perform this action” and i have tried in two different android phones but it still appear the same..
    what should i do? help please

  10. Hi sir
    Thank you so much for the above article.
    i was struct from last 2 days for upload file to server. finally i got this

    But i am getting one problem
    i am not able to upload to the server.
    not able to see the file in hosting

    Please help me

  11. This code does not work whatsoever on API level 23. You have to check for the permissions at runtime and this code does not implement that. Whoever says this is working is on some outdated API level. It says that this post was updated a week ago, but it’s not.

  12. Hi Vamsi, love the solution, but the PHP script is pretty open to exploitation. You probably want to upload outside the webroot (or at the very least lock that directory down using .htaccess). If you don’t any manner of file can be uploaded to allow a third party to create a php terminal.

  13. How can return data from server and show it in this function
    i need to return saved image name after uploaded to server to show it in mobile app

    1. If you want to send multiple parameters, replace

      //+++++++++++++++

      //writing bytes to data outputstream
      dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);

      dataOutputStream.writeBytes(“Content-Disposition: form-data; name=”uploaded_file”;filename=”” + selectedFilePath + “”” + lineEnd);
      dataOutputStream.writeBytes(lineEnd);

      //+++++++++++++++

      replace:

      //++++++++++++++

      //writing bytes to data outputstream
      dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);

      int photo_id = 1;

      dataOutputStream.writeBytes(“Content-Disposition: form-data; name=”photo_id”” + lineEnd + lineEnd); // param name
      dataOutputStream.writeBytes( photo_id + lineEnd + twoHyphens + boundary + lineEnd); // param value

      String photo_name = “My First Photo”;

      dataOutputStream.writeBytes(“Content-Disposition: form-data; name=”photo_name”” + lineEnd + lineEnd); // param name
      dataOutputStream.writeBytes(photo_name + lineEnd + twoHyphens + boundary + lineEnd); // param value

      dataOutputStream.writeBytes(“Content-Disposition: form-data; name=”uploadfile”;filename=””+ selectedFilePath + “”” + lineEnd);
      dataOutputStream.writeBytes(lineEnd);

      //++++++++++++++

  14. Hi sir,
    nice example, there is small error while uploading file on server, how to solve this error, please explain me
    W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Download/lordkrishna.mp3 (Permission denied)
    W/System.err: at java.io.FileInputStream.open(Native Method)
    W/System.err: at java.io.FileInputStream.(FileInputStream.java:146)
    W/System.err: at com.example.moraya.upload1.MainActivity.uploadFile(MainActivity.java:142)
    W/System.err: at com.example.moraya.upload1.MainActivity$1.run(MainActivity.java:65)
    W/System.err: at java.lang.Thread.run(Thread.java:761)
    E/EGL_emulation: tid 2422: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
    W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x968f1180, error=EGL_BAD_MATCH
    E/EGL_emulation: tid 2422: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
    W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x968f1240, error=EGL_BAD_MATCH

    Thank you so much

  15. Hi
    what if i have two attachments in one screen,can the method onActivityResult be duplicated to allow multiple uses in the same page please help
    thanks!

  16. Why i can’t see my uploaded file in my server.but this app showing message that im successfully upload the file

  17. Thanks!!!Great Work!! I can upload to my localhost and domain but at my linux server seem doesn’t work

  18. Thank you so much sir it was very helpful for me.
    sir i hv an query that
    what should i do if i want to rename the file to the particular string. and then the file is upload with the new name on the server..

  19. hi sir
    Thank u so much, it worked for me.
    but, when i run it on my phone, the application is force close
    please help…

  20. Sir i am getting File not found after click on upload button.Please help me why it is giving such type error.
    In logcat it is showing this error
    java.io.FileNotFoundException: /storage/emulated/0/Android/data/net.one97.paytm/files/Download/Invoice3369664106.pdf: open failed: EACCES (Permission denied)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.