Android Upload File to sever with Camera Image, Video

Hi guys! Today we are going to code on how to send data from Android to PHP server. This is an example app that can post a file and text data to a web server with PHP file as a receiver. Having the ability to (do HTTP Post Request) post data from android app to remote server is required for most apps. Here are some example use of this functionality:

1. MainActivity.java

package com.tutorialsee;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

   // LogCat tag
    private static final String TAG = MainActivity.class.getSimpleName();
    // Camera activity request codes
    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;
    private Uri fileUri; // file url to store image/video
    private Button btnCapturePicture, btnRecordVideo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
        btnRecordVideo = (Button) findViewById(R.id.btnRecordVideo);
        //Capture image button click event
        btnCapturePicture.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // capture picture
                captureImage();
            }
        });

        //Record video button click event
        btnRecordVideo.setOnClickListener(new View.OnClickListener() {
             @Override
            public void onClick(View v) {
                // record video
                recordVideo();
            }
        });

        // Checking camera availability
        if (!isDeviceSupportCamera()) {
            Toast.makeText(getApplicationContext(),
                    "Sorry! Your device doesn't support camera",
                    Toast.LENGTH_LONG).show();
            // will close the app if the device does't have camera
            finish();
        }
    }

    //Checking device has camera hardware or not
    private boolean isDeviceSupportCamera() {
        if (getApplicationContext().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }

    //Launching camera app to capture image
    private void captureImage() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        // start the image capture Intent
        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
    }
   
    //Launching camera app to record video
    private void recordVideo() {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
        // set video quality
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
                                                            // name

        // start the video capture Intent
        startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
    }

   
      //Here we store the file url as it will be null after returning from camera app
     @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
         // save file url in bundle as it will be null on screen orientation
        // changes
        outState.putParcelable("file_uri", fileUri);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
         // get the file url
        fileUri = savedInstanceState.getParcelable("file_uri");
    }
   //Receiving activity result method will be called after closing the camera
   
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // if the result is capturing Image
        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
               
            // successfully captured the image
                // launching upload activity
            launchUploadActivity(true);
          } else if (resultCode == RESULT_CANCELED) {
           // user cancelled Image capture
                Toast.makeText(getApplicationContext(),"User cancelled image capture", Toast.LENGTH_SHORT).show();
           
            } else {
                // failed to capture image
                Toast.makeText(getApplicationContext(),"Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
            }
       
        } else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
               // video successfully recorded
                // launching upload activity
            launchUploadActivity(false);
           
            } else if (resultCode == RESULT_CANCELED) {
               // user cancelled recording
                Toast.makeText(getApplicationContext(),"User cancelled video recording", Toast.LENGTH_SHORT).show();
           
            } else {
                // failed to record video
                Toast.makeText(getApplicationContext(),"Sorry! Failed to record video", Toast.LENGTH_SHORT).show();
            }
        }
    }
   
    private void launchUploadActivity(boolean isImage){
    Intent i = new Intent(MainActivity.this, UploadActivity.class);
        i.putExtra("filePath", fileUri.getPath());
        i.putExtra("isImage", isImage);
        startActivity(i);
    }
    
    // ------------ Helper Methods ----------------------
  

    //Creating file uri to store image/video
    public Uri getOutputMediaFileUri(int type) {
        return Uri.fromFile(getOutputMediaFile(type));
    }

// returning image / video
    private static File getOutputMediaFile(int type) {
        // External sdcard location
        File mediaStorageDir = new File(
                Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),Constant.IMAGE_DIRECTORY_NAME);

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d(TAG, "Oops! Failed create " + Constant.IMAGE_DIRECTORY_NAME + " directory");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.getDefault()).format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
        } else if (type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
        } else {
            return null;
        }
         return mediaFile;
    }
}

2. UploadActivity.java

package com.tutorialsee;

import com.tutorialsee.AndroidMultiPartEntity.ProgressListener;
import java.io.File;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;

@TargetApi(Build.VERSION_CODES.HONEYCOMB) public class UploadActivity extends Activity {
// LogCat tag
private static final String TAG = MainActivity.class.getSimpleName();
private ProgressBar progressBar;
private String filePath = null;
private TextView txtPercentage;
private ImageView imgPreview;
private VideoView vidPreview;
private Button btnUpload;
long totalSize = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload);
txtPercentage = (TextView) findViewById(R.id.txtPercentage);
btnUpload = (Button) findViewById(R.id.btnUpload);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
imgPreview = (ImageView) findViewById(R.id.imgPreview);
vidPreview = (VideoView) findViewById(R.id.videoPreview);

// Receiving the data from previous activity
Intent i = getIntent();

// image or video path that is captured in previous activity
filePath = i.getStringExtra("filePath");

// boolean flag to identify the media type, image or video
boolean isImage = i.getBooleanExtra("isImage", true);

if (filePath != null) {
// Displaying the image or video on the screen
previewMedia(isImage);
} else {
Toast.makeText(getApplicationContext(),"Sorry, file path is missing!", Toast.LENGTH_LONG).show();
}

btnUpload.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// uploading the file to server
new UploadFileToServer().execute();
}
});

}

//Displaying captured image/video on the screen

private void previewMedia(boolean isImage) {
// Checking whether captured media is image or video
if (isImage) {
imgPreview.setVisibility(View.VISIBLE);
vidPreview.setVisibility(View.GONE);
// bimatp factory
BitmapFactory.Options options = new BitmapFactory.Options();

// down sizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 8;
final Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
imgPreview.setImageBitmap(bitmap);
} else {
imgPreview.setVisibility(View.GONE);
vidPreview.setVisibility(View.VISIBLE);
vidPreview.setVideoPath(filePath);
// start playing
vidPreview.start();
}
}

// Uploading the file to server
private class UploadFileToServer extends AsyncTask<Void, Integer, String> {
@Override
protected void onPreExecute() {
// setting progress bar to zero
progressBar.setProgress(0);
super.onPreExecute();
}

@Override
protected void onProgressUpdate(Integer... progress) {
// Making progress bar visible
progressBar.setVisibility(View.VISIBLE);
// updating progress bar value
progressBar.setProgress(progress[0]);
// updating percentage value
txtPercentage.setText(String.valueOf(progress[0]) + "%");
}

@Override
protected String doInBackground(Void... params) {
return uploadFile();
}

@SuppressWarnings("deprecation")
private String uploadFile() {
String responseString = null;
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(Constant.FILE_UPLOAD_URL);
try {
AndroidMultiPartEntity entity = new AndroidMultiPartEntity(new ProgressListener() {

@Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
});

File sourceFile = new File(filePath);
// Adding file data to http body
entity.addPart("image", new FileBody(sourceFile));
// Extra parameters if you want to pass to server
entity.addPart("website",new StringBody("www.tutorialsee.com"));
entity.addPart("email", new StringBody("tutorialsee9@gmail.com"));
totalSize = entity.getContentLength();
httppost.setEntity(entity);

// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();

int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "+ statusCode;
}

} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}

return responseString;

}

@Override
protected void onPostExecute(String result) {
Log.e(TAG, "Response from server: " + result);
// showing the server response in an alert dialog
showAlert(result);
super.onPostExecute(result);
}
}

//Method to show alert dialog
private void showAlert(String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message).setTitle("Response from Servers").setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent i = new Intent(getBaseContext(), MainActivity.class);
startActivity(i);
}
});
AlertDialog alert = builder.create();
alert.show();

}
}

3. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/view_background"
    android:baselineAligned="false"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btnCapturePicture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="0.1dp"
        android:layout_weight="1"
        android:background="@color/btn_bg"
        android:text="@string/btnTakePicture"
        android:textColor="@color/white"
        android:textSize="25sp" />

    <Button
        android:id="@+id/btnRecordVideo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@color/btn_bg"
        android:text="@string/btnRecordVideo"
        android:textColor="@color/white"
        android:textSize="25sp" />

</LinearLayout>

4. activity_upload.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/view_background"
    android:orientation="vertical"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/imgPreview"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:layout_marginTop="15dp"
        android:visibility="gone" />

    <VideoView
        android:id="@+id/videoPreview"
        android:layout_width="fill_parent"
        android:layout_height="400dp"
        android:layout_marginTop="15dp"
        android:visibility="gone" />

    <TextView
        android:id="@+id/txtPercentage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="15dp"
        android:layout_marginTop="15dp"
        android:textColor="@color/txt_font"
        android:textSize="30dp" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="20dp"
        android:layout_marginBottom="35dp"
        android:visibility="gone" />

    <Button
        android:id="@+id/btnUpload"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="20dp"
        android:background="@color/btn_bg"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:text="@string/btnUploadToServer"
        android:textColor="@color/white" />

</LinearLayout>