Take a Photo from Android Camera and Upload it to a Remote PHP Server

In this tutorial, I’d like to share how to write a simple Android application to take a picture, as well as upload the image to a remote PHP server. Let’s get started with a simple Java application.

Dynamsoft Barcode Reader SDK
Ads Powered by Dynamsoft

android_upload_clientandroid_upload_server

Uploading Images with Java

Download the latest HttpClient 4.3.4 from Apache Software Foundation.

Add following jar files:

java_upload_libs

Learn the sample code and make your own application:

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost("http://localhost:8003/savetofile.php"); // your server

            FileBody bin = new FileBody(new File("my.jpg")); // image for uploading

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("myFile", bin)
                    .build();

            httppost.setEntity(reqEntity);

            System.out.println("executing request " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
	}

Taking a Photo with Android Camera

It is pretty easy to invoke camera app to take a picture on Android, referring to the article Taking Photos Simply provided by Google. So I just talk a little bit of it.

Call camera app with intent:

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);

Get the thumbnail returned from the camera:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 0 && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        mImageView.setImageBitmap(imageBitmap);
    }
}

If you want to get an image with better quality, you need to provide an image saving path to the camera app.

Therefore, add the permissions to AndroidManifest.xml:

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

Improve the intent:

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
Intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(intent, 0);

Decode the image file when the result is returned:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == 0 && resultCode == Activity.RESULT_OK) {
			setPic();
		}
}

private void setPic() {
    // Get the dimensions of the View
    int targetW = mImageView.getWidth();
    int targetH = mImageView.getHeight();

    // Get the dimensions of the bitmap
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    // Determine how much to scale down the image
    int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

    // Decode the image file into a Bitmap sized to fill the View
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    mImageView.setImageBitmap(bitmap);
}

Image Transmission from Android Client to PHP Server

Now, we can combine the two functionalities to enhance the Android application.

To access the Internet, add the following permission to AndroidManifest.xml:

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

Refer to http://blog.rafaelsanches.com/2011/01/29/upload-using-multipart-post-using-httpclient-in-android/, create a class MultipartEntity:

public class MultipartEntity implements HttpEntity {

    private String boundary = null;

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    boolean isSetLast = false;
    boolean isSetFirst = false;

    public MultipartEntity() {
        this.boundary = System.currentTimeMillis() + "";
    }

    public void writeFirstBoundaryIfNeeds(){
        if(!isSetFirst){
            try {
                out.write(("--" + boundary + "\r\n").getBytes());
            } catch (final IOException e) {

            }
        }
        isSetFirst = true;
    }

    public void writeLastBoundaryIfNeeds() {
        if(isSetLast){
            return ;
        }
        try {
            out.write(("\r\n--" + boundary + "--\r\n").getBytes());
        } catch (final IOException e) {

        }
        isSetLast = true;
    }

    public void addPart(final String key, final String value) {
        writeFirstBoundaryIfNeeds();
        try {
            out.write(("Content-Disposition: form-data; name=\"" +key+"\"\r\n").getBytes());
            out.write("Content-Type: text/plain; charset=UTF-8\r\n".getBytes());
            out.write("Content-Transfer-Encoding: 8bit\r\n\r\n".getBytes());
            out.write(value.getBytes());
            out.write(("\r\n--" + boundary + "\r\n").getBytes());
        } catch (final IOException e) {

        }
    }

    public void addPart(final String key, final String fileName, final InputStream fin){
        addPart(key, fileName, fin, "application/octet-stream");
    }

    public void addPart(final String key, final String fileName, final InputStream fin, String type){
        writeFirstBoundaryIfNeeds();
        try {
            type = "Content-Type: "+type+"\r\n";
            out.write(("Content-Disposition: form-data; name=\""+ key+"\"; filename=\"" + fileName + "\"\r\n").getBytes());
            out.write(type.getBytes());
            out.write("Content-Transfer-Encoding: binary\r\n\r\n".getBytes());

            final byte[] tmp = new byte[4096];
            int l = 0;
            while ((l = fin.read(tmp)) != -1) {
                out.write(tmp, 0, l);
            }
            out.flush();
        } catch (final IOException e) {

        } finally {
            try {
                fin.close();
            } catch (final IOException e) {

            }
        }
    }

    public void addPart(final String key, final File value) {
        try {
            addPart(key, value.getName(), new FileInputStream(value));
        } catch (final FileNotFoundException e) {

        }
    }

    @Override
    public long getContentLength() {
        writeLastBoundaryIfNeeds();
        return out.toByteArray().length;
    }

    @Override
    public Header getContentType() {
        return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
    }

    @Override
    public boolean isChunked() {
        return false;
    }

    @Override
    public boolean isRepeatable() {
        return false;
    }

    @Override
    public boolean isStreaming() {
        return false;
    }

    @Override
    public void writeTo(final OutputStream outstream) throws IOException {
        outstream.write(out.toByteArray());
    }

    @Override
    public Header getContentEncoding() {
        return null;
    }

    @Override
    public void consumeContent() throws IOException,
    UnsupportedOperationException {
        if (isStreaming()) {
            throw new UnsupportedOperationException(
            "Streaming entity does not implement #consumeContent()");
        }
    }

    @Override
    public InputStream getContent() throws IOException,
    UnsupportedOperationException {
        return new ByteArrayInputStream(out.toByteArray());
    }

}

Use AsyncTask to process the uploading work:

private class UploadTask extends AsyncTask<Bitmap, Void, Void> {

		protected Void doInBackground(Bitmap... bitmaps) {
			if (bitmaps[0] == null)
				return null;

			Bitmap bitmap = bitmaps[0];
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); // convert Bitmap to ByteArrayOutputStream
			InputStream in = new ByteArrayInputStream(stream.toByteArray()); // convert ByteArrayOutputStream to ByteArrayInputStream

			DefaultHttpClient httpclient = new DefaultHttpClient();
			try {
				HttpPost httppost = new HttpPost(
						"http://192.168.8.84:8003/savetofile.php"); // server

				MultipartEntity reqEntity = new MultipartEntity();
				reqEntity.addPart("myFile",
						System.currentTimeMillis() + ".jpg", in);
				httppost.setEntity(reqEntity);

				Log.i(TAG, "request " + httppost.getRequestLine());
				HttpResponse response = null;
				try {
					response = httpclient.execute(httppost);
				} catch (ClientProtocolException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				try {
					if (response != null)
						Log.i(TAG, "response " + response.getStatusLine().toString());
				} finally {

				}
			} finally {

			}

			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Toast.makeText(MainActivity.this, R.string.uploaded, Toast.LENGTH_LONG).show();
		}
	}

Source Code

https://github.com/yushulx/JavaHTTPUpload

  • Manuel Lama Paniagua

    Uploading Images with Java
    Download the latest HttpClient 4.3.4 from Apache Software Foundation.

    Add following jar files:

    Did you do that part? Your error says: NoSuchMethodError: org.apache.http.impl.client

  • Jie Wei

    Hi benedict,how do you solve the error you posted here?

  • Jie Wei

    https://uploads.disquscdn.com/images/52ac499e8fc5d956cb32f25886b18b244ec6c850ddb9e8b0a3da198d38baa851.png

    Hi,i’m hving this error(the figure shown below),can someone else help me to solve this error?Thanks in advanced!

  • http://www.bestqsystems.com Benson QSystems

    You have not defined mCurrentPhotoPath…

  • Benedict

    Hi. I’m Having an error with the HTTP CLIENT. Not sure whether there is an error with the dependencies. I am using JDK1.7 btw.

    FATAL EXCEPTION: AsyncTask #1

    Process: benchinpteltd.benapp, PID: 23177

    java.lang.RuntimeException: An error occured while executing doInBackground()

    at android.os.AsyncTask$3.done(AsyncTask.java:300)

    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)

    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)

    at java.util.concurrent.FutureTask.run(FutureTask.java:242)

    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)

    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)

    at java.lang.Thread.run(Thread.java:841)

    Caused by: java.lang.NoSuchMethodError: org.apache.http.impl.client.DefaultHttpClient.execute

    at benchinpteltd.benapp.TakesPhoto2$UploadTask.doInBackground(TakesPhoto2.java:124)

    at benchinpteltd.benapp.TakesPhoto2$UploadTask.doInBackground(TakesPhoto2.java:99)

  • issak

    i did all steps and java file upload my.jpg but mobile didn’t and not appear toast however no error in code i just import and used xamp server and java success assess why i need reply please ???

  • Mayank

    Hello Aagii,
    Actually i want to know where to place Main.java which is under java/src/com/main folder..

  • Brobby

    Thank you for this but I was just wondering if it’s possible to give an example on how to upload other files i.e .xls, .doc, pdf etc TIA

  • Aditi Kulkarni

    Thank you for quick response

    I have compress bitmap using JPEG and save it as .jpg.

    Following is php code :

  • http://www.dynamsoft.com/ Xiao Ling

    Did you add suffix to the uploaded images? xx.png or xx.jpg? If you can’t open pictures with any photo viewer, probably you didn’t save the data correctly in PHP.

  • Aditi Kulkarni

    Thank you for blog. It is really helpful. With some php code changes I am able to upload image but I am not able to open uploaded file with any photo viewer do I need to set any more properties to bitmap to make it visible ?

    Thanks in advance

  • Aditi Kulkarni

    Thank you for quick reply

  • http://www.dynamsoft.com/ Xiao Ling

    Get the source code on GitHub. You will see how to use AsyncTask.

  • Aditi Kulkarni

    I have one query … I am not able to figure out where are yu calling Async Task (UploadTask) in your code. Can you please explain that code part.

    Thanks in advance

  • http://www.dynamsoft.com/ Xiao Ling

    Two ways: 1. change camera setting to make source picture smaller. 2. set inSampleSize value greater than 1 (If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.) when using BitmapFactory.

  • Birendra

    Hi, the image size is huge as the picture is taken from 5mp camera… is there any way to reduce or compress the image before sending to server?

  • http://www.dynamsoft.com Desmond Shaw

    Have you created the folder for uploading files?

  • Chinnmayi

    Hi I am new to android and I want to upload images to the wamp or xampp server. I downloaded the code but my doubt is where to place that main file and I tried running these code but its showing unfortunately stopped can u please help me to resolve these problem please…

  • Chinnmayi

    I am not getting where to add that java folder main file and whats the use of that file

  • http://www.dynamsoft.com Desmond Shaw

    Have you analyzed the crash log?

  • Chinnmayi

    Hiii…
    I downloaded this code and tried to run it, but i have doubt that where to add java code and when i try to run this code it captures the images and then shows unfortunately,picupload has stopped.
    please help me to solve this problem

  • mastmurgi

    Hii thanks for this codes.
    I have one question actually in my project i want to show the name of the image that has been uploaded. So please tell me how to get the name of uploading image in java code.

  • Devraj

    Hey Desmond….

    We are using ROR on our server side for our API.

    When i try to upload image along with some other params….it’s giving me “incomplete response received from application”. Any Idea? Please let me know..:)

  • swapnil

    i m new so pls tell me step by step too put php script code where i write…i dont know so pls

  • http://www.agilebasics.com Abraham George Chackungal

    Thanks to you Desmond for the source code and explanations.

  • http://www.dynamsoft.com Desmond Shaw

    Excellent! Thanks!

  • http://www.agilebasics.com Abraham George Chackungal

    incase someone have problem in not seeing the image in a server like ubuntu even when the app mentions the file is uploaded successfully try this:

    Step #1 Create an uploads folder in the same path where savetofile.php
    mkdir uploads
    Step #2 Enable full permission to the folder
    chmod 777 uploads

    NOW Try running the image send again and see if the image is uploaded under uploads folder.

    If the image is still not uploaded under uploads folder try this

    Change the php.ini to enable file upload. for this first locate where your php.ini file is (apache2/php.ini)
    locate php.ini
    Example path: /etc/php5/apache2/php.ini

    Ensure the file_upload is On
    file_uploads = On
    and you are allowed to upload a big size image
    upload_max_filesize = 10M

    Try the app again Hope it helps

  • http://www.dynamsoft.com Desmond Shaw

    Did you create the uploading folder ‘uploads’? Check the PHP code: move_uploaded_file($_FILES[‘myFile’][‘tmp_name’], “uploads/” . $_FILES[‘myFile’][‘name’]);

  • Rudresh A

    yeah i have got the same problem

  • amadeus

    hi, thank you very much for this tutorial, I am still a beginner in android but I have tried your code and it worked successfully, I took a photo and uploaded it to the server (xamp apache server) but I just need your help I have checked all the files inside the xamp folder I couldnt find the folder where the images should be stored in, can you please assist? many thanks in advance

  • glady

    actuallyi got connection refused err….xampp is running…

    11-30 18:34:37.774: W/System.err(857): org.apache.http.conn.HttpHostConnectException: Connection to http://192.168.1.103:8003 refused

  • KerryCleary

    I’m looking for an Android developer to write an app that is a modification on this theme. The app would be used inside our small business. The basic concept would be to have the user input some tagging information, take a bunch of picture, and then save them to a central server (on internal LAN) with that tagging information being used to later locate the pictures in question. Would you be interested?

  • Will

    When I run this I don’t get any errors and I’m getting the following in my log cat:

    Photo Upload(19744): request POST http://192.168.0.104/hometownPHPs/ HTTP/1.1

    ^^^^
    (there’s a space after hometownPHPs… (/ HTTP/1.1). I created a folder to match this path but nothing showed up.

    Photo Upload Response(19744): response HTTP/1.1 200 OK

    I used the PHP code you provided. I don’t really know what’s going on.. :S

  • Will

    Nevermind I checked out your source code. I’ll figure it out.

  • Will

    What is photoFile? You don’t declare it anywhere. Thanks.

  • http://www.dynamsoft.com Desmond Shaw

    My pleasure

  • Aditya

    Wow Its a great tutorial it helped me a lot Thanks for sharing

  • http://www.dynamsoft.com Desmond Shaw

    Hi, I mentioned how to get the full size image from the paragraph “If you want to get an image with better quality, you need to provide an image saving path to the camera app.”

  • Steve G

    As far as im aware,
    Bundle extras = data.getExtras();
    Bitmap imageBitmap = (Bitmap) extras.get(“data”);
    is only going to return a thumbnail of the image. How can we do this with a full size image?