How to upload image to Java server?

In this post, I will be discussing about how to upload an Image present in Gallery App to Java server (For ex: Apache Tomcat).

What is Android Gallery?

Android device has Gallery application installed by default which contains images and videos. It is the place where the images and videos you download from internet or upload from your computer can be viewed.

What are we going to develop?

The application which we are going to develop will allow you to select an Image from Gallery application, display it inside app and upload it to Java server.

This application supports image selection from Gallery application and it may not work as expected if you pick Image from other image applications (like Google Photos application present in higher version of Android). I will write separate post later on how to pick Images from sources other than Gallery app.

You can download source code from here if you don’t want to create Application from scratch, otherwise please proceed with below listings.

Developing the application involves two parts:

  1. Android Application – To upload Image to Java server
  2. Java web application – To store Image posted by Android application in server

Android Application

Let us start with creating Android application first, then we will jump into Java web application creation.

Steps involved in uploading Image to Java server are:

  1. Open Gallery app, select an Image and set it in Imageview of the application. I strongly recommend you to take a quick look on this post – How to pick image from gallery? to get an understanding on picking Image from Gallery.
  2. Encoding – Convert the selected Image into String using Base64 Utility Class. Use AsynTask to encode Image to String since it is long running process. Once encoding is done, call ‘triggerImageUpload’ method which will initiate Image uploading.
    public void encodeImagetoString() {
    		new AsyncTask<Void, Void, String>() {
    
    			protected void onPreExecute() {
    
    			};
    
    			@Override
    			protected String doInBackground(Void... params) {
    				BitmapFactory.Options options = null;
    				options = new BitmapFactory.Options();
    				options.inSampleSize = 3;
    				bitmap = BitmapFactory.decodeFile(imgPath,
    						options);
    				ByteArrayOutputStream stream = new ByteArrayOutputStream();
    				// Must compress the Image to reduce image size to make upload easy
    				bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream); 
    				byte[] byte_arr = stream.toByteArray();
    				// Encode Image to String
    				encodedString = Base64.encodeToString(byte_arr, 0);
    				return "";
    			}
    
    			@Override
    			protected void onPostExecute(String msg) {
    				prgDialog.setMessage("Calling Upload");
    				// Put converted Image string into Async Http Post param
    				params.put("image", encodedString);
    				// Trigger Image upload
    				triggerImageUpload();
    			}
    		}.execute(null, null, null);
    	}
  3. Post Encoded String to through HTTP to Java server using AsyncHttp library. (You can also use Volley library, it is upto you, you can use any HTTP library). Method ‘triggerImageUpload’ gets called in onPostExecute method when Encoding is complete:
    public void triggerImageUpload() {
    		makeHTTPCall();
    	}

    Post Encoded String to Java server:

    public void makeHTTPCall() {
    		prgDialog.setMessage("Invoking JSP");		
    		AsyncHttpClient client = new AsyncHttpClient();
    		// Don't forget to change the IP address to your LAN address. Port no as well.
    		client.post("http://192.168.2.5:9999/ImageUploadWebApp/uploadimg.jsp",
    				params, new AsyncHttpResponseHandler() {
    					// When the response returned by REST has Http
    					// response code '200'
    					@Override
    					public void onSuccess(String response) {
    						// Hide Progress Dialog
    						prgDialog.hide();
    						Toast.makeText(getApplicationContext(), response,
    								Toast.LENGTH_LONG).show();
    					}
    
    					// When the response returned by REST has Http
    					// response code other than '200' such as '404',
    					// '500' or '403' etc
    					@Override
    					public void onFailure(int statusCode, Throwable error,
    							String content) {
    						// Hide Progress Dialog
    						prgDialog.hide();
    						// When Http response code is '404'
    						if (statusCode == 404) {
    							Toast.makeText(getApplicationContext(),
    									"Requested resource not found",
    									Toast.LENGTH_LONG).show();
    						}
    						// When Http response code is '500'
    						else if (statusCode == 500) {
    							Toast.makeText(getApplicationContext(),
    									"Something went wrong at server end",
    									Toast.LENGTH_LONG).show();
    						}
    						// When Http response code other than 404, 500
    						else {
    							Toast.makeText(
    									getApplicationContext(),
    									"Error Occured n Most Common Error: n1. Device not connected to Internetn2. Web App is not deployed in App servern3. App server is not runningn HTTP Status code : "
    											+ statusCode, Toast.LENGTH_LONG)
    									.show();
    						}
    					}
    				});
    	}
  4. Based on the HTTP response returned by Java server, inform User about the upload status (Uploaded successfully or Failed)

Okay enough theory, let us create application:
Step 1: Create Android Application Project

  • Create new android project [File >> New >> Android Application Project] with project name JavaImageUpload
  • Enter package name as ‘com.prgguru.example’ and activity name as ‘MainActivity’
  • Choose Minimum Required SDK, Target SDK and Compile with. Confused on choosing these options? Take a look at Minimum Required SDK – Target SDK – Compile With post.
  • Click Next button and finally click ‘Finish’ to create project

Step 2: Add library to project

Add below third party library into project’s ‘libs’ folder. You can also download it if you don’t have it with you.

1. Android Asynchronous Http Client – An asynchronous callback-based Http client for Android built on top of Apache’s HttpClient libraries which is used by Pinterest, Instagram etc.,. Download

Step 3: Design screen

Open activity_main.xml and replace it with below code. Application screen has ImageView and Two buttons (One to pick Image from Gallery and other from to upload Image to Java server).

<?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:orientation="vertical" >

    <ImageView
        android:id="@+id/imgView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" >
    </ImageView>

    <Button
        android:id="@+id/buttonLoadPicture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="0"
        android:onClick="loadImagefromGallery"
        android:text="Load Picture" >
    </Button>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:onClick="uploadImage"
        android:text="Upload" />

</LinearLayout>

Screen will look like:

Layout_Screen

Step 4: MainActivity.java – Main Class

Open MainActivity.java and replace it with below code.

Each line of code is commented well, if you still have any doubt or question discuss it.

package com.prgguru.example;

import java.io.ByteArrayOutputStream;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

@SuppressLint("NewApi")
public class MainActivity extends Activity {
	ProgressDialog prgDialog;
	String encodedString;
	RequestParams params = new RequestParams();
	String imgPath, fileName;
	Bitmap bitmap;
	private static int RESULT_LOAD_IMG = 1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		prgDialog = new ProgressDialog(this);
		// Set Cancelable as False
		prgDialog.setCancelable(false);
	}

	public void loadImagefromGallery(View view) {
		// Create intent to Open Image applications like Gallery, Google Photos
		Intent galleryIntent = new Intent(Intent.ACTION_PICK,
				android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		// Start the Intent
		startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
	}

	// When Image is selected from Gallery
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		try {
			// When an Image is picked
			if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
					&& null != data) {
				// Get the Image from data

				Uri selectedImage = data.getData();
				String[] filePathColumn = { MediaStore.Images.Media.DATA };

				// Get the cursor
				Cursor cursor = getContentResolver().query(selectedImage,
						filePathColumn, null, null, null);
				// Move to first row
				cursor.moveToFirst();

				int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
				imgPath = cursor.getString(columnIndex);
				cursor.close();
				ImageView imgView = (ImageView) findViewById(R.id.imgView);
				// Set the Image in ImageView
				imgView.setImageBitmap(BitmapFactory
						.decodeFile(imgPath));
				// Get the Image's file name
				String fileNameSegments[] = imgPath.split("/");
				fileName = fileNameSegments[fileNameSegments.length - 1];
				// Put file name in Async Http Post Param which will used in Java web app
				params.put("filename", fileName);

			} else {
				Toast.makeText(this, "You haven't picked Image",
						Toast.LENGTH_LONG).show();
			}
		} catch (Exception e) {
			Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
					.show();
		}

	}
	
	// When Upload button is clicked
	public void uploadImage(View v) {
		// When Image is selected from Gallery
		if (imgPath != null && !imgPath.isEmpty()) {
			prgDialog.setMessage("Converting Image to Binary Data");
			prgDialog.show();
			// Convert image to String using Base64
			encodeImagetoString();
		// When Image is not selected from Gallery
		} else {
			Toast.makeText(
					getApplicationContext(),
					"You must select image from gallery before you try to upload",
					Toast.LENGTH_LONG).show();
		}
	}

	// AsyncTask - To convert Image to String
	public void encodeImagetoString() {
		new AsyncTask<Void, Void, String>() {

			protected void onPreExecute() {

			};

			@Override
			protected String doInBackground(Void... params) {
				BitmapFactory.Options options = null;
				options = new BitmapFactory.Options();
				options.inSampleSize = 3;
				bitmap = BitmapFactory.decodeFile(imgPath,
						options);
				ByteArrayOutputStream stream = new ByteArrayOutputStream();
				// Must compress the Image to reduce image size to make upload easy
				bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream); 
				byte[] byte_arr = stream.toByteArray();
				// Encode Image to String
				encodedString = Base64.encodeToString(byte_arr, 0);
				return "";
			}

			@Override
			protected void onPostExecute(String msg) {
				prgDialog.setMessage("Calling Upload");
				// Put converted Image string into Async Http Post param
				params.put("image", encodedString);
				// Trigger Image upload
				triggerImageUpload();
			}
		}.execute(null, null, null);
	}
	
	public void triggerImageUpload() {
		makeHTTPCall();
	}

	// Make Http call to upload Image to Java server
	public void makeHTTPCall() {
		prgDialog.setMessage("Invoking JSP");		
		AsyncHttpClient client = new AsyncHttpClient();
		// Don't forget to change the IP address to your LAN address. Port no as well.
		client.post("http://192.168.2.5:9999/ImageUploadWebApp/uploadimg.jsp",
				params, new AsyncHttpResponseHandler() {
					// When the response returned by REST has Http
					// response code '200'
					@Override
					public void onSuccess(String response) {
						// Hide Progress Dialog
						prgDialog.hide();
						Toast.makeText(getApplicationContext(), response,
								Toast.LENGTH_LONG).show();
					}

					// When the response returned by REST has Http
					// response code other than '200' such as '404',
					// '500' or '403' etc
					@Override
					public void onFailure(int statusCode, Throwable error,
							String content) {
						// Hide Progress Dialog
						prgDialog.hide();
						// When Http response code is '404'
						if (statusCode == 404) {
							Toast.makeText(getApplicationContext(),
									"Requested resource not found",
									Toast.LENGTH_LONG).show();
						}
						// When Http response code is '500'
						else if (statusCode == 500) {
							Toast.makeText(getApplicationContext(),
									"Something went wrong at server end",
									Toast.LENGTH_LONG).show();
						}
						// When Http response code other than 404, 500
						else {
							Toast.makeText(
									getApplicationContext(),
									"Error Occured n Most Common Error: n1. Device not connected to Internetn2. Web App is not deployed in App servern3. App server is not runningn HTTP Status code : "
											+ statusCode, Toast.LENGTH_LONG)
									.show();
						}
					}
				});
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		// Dismiss the progress bar when application is closed
		if (prgDialog != null) {
			prgDialog.dismiss();
		}
	}
}

Step 5: Add permission in AndroidManifest.xml

Add Internet and Storage permission in AndroidManifest:

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

[pglinkadssmall1]

So far we created Android application, now let us create Java web application and deploy it in Apache Tomcat server.

Java web application

Create Dynamic web application named ‘ImageUploadWebApp’ in Eclipse with the files highlighted in the below screen-shot (You can download Web application from here if you don’t want to create it from scratch) :

JSP_Web_App

Add Codec Library to lib folder

Download Codec library from here and place it under lib folder. Library is used to Decode the String posted from Android application to Image.

Create ManipulateImage Class under src folder

This class will convert the Encoded String posted by Android application to Image and store it under the path specified.

package com.prgguru.webapp;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.codec.binary.Base64;

public class ManipulateImage {

	// Decode String into an Image
	public static void convertStringtoImage(String encodedImageStr,	String fileName) {

		try {
			// Decode String using Base64 Class
			byte[] imageByteArray = Base64.decodeBase64(encodedImageStr); 

			// Write Image into File system - Make sure you update the path
			FileOutputStream imageOutFile = new FileOutputStream("G:/Studys/UploadedImages/" + fileName);
			imageOutFile.write(imageByteArray);

			imageOutFile.close();

			System.out.println("Image Successfully Stored");
		} catch (FileNotFoundException fnfe) {
			System.out.println("Image Path not found" + fnfe);
		} catch (IOException ioe) {
			System.out.println("Exception while converting the Image " + ioe);
		}

	}

}

uploadimg.jsp

Create JSP under WebContent folder:

<%@page import="com.prgguru.webapp.ManipulateImage"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%
	String imgEncodedStr = request.getParameter("image");
String fileName = request.getParameter("filename");
System.out.println("Filename: "+ fileName);
if(imgEncodedStr != null){
	ManipulateImage.convertStringtoImage(imgEncodedStr, fileName);
	System.out.println("Inside if");
	out.print("Image upload complete, Please check your directory");
} else{
	System.out.println("Inside else");
	out.print("Image is empty");	
}
%>

Encoded Image (image converted to String) from Android application will be posted to uploadimg.jsp which will decode the String to Image and store it under the folder specified.

That’s all. Now run the webapp on Apache Tomcat server or any Java server you configured in your machine.

Demo

That’s all. It’s time to test our code.

Run the application using emulator or device by right clicking on the project >> Run as >> Android applicaiton >> Choose emulator or device.



Download Source Code

Entire project is zipped and is available for download. Unzip the downloaded project and to import the project into eclipse, launch eclipse >> File >> Import.. >> Choose downloaded project (How to import android project in eclipse).

Download Source Code

*apk in Android  is the installation file similar to exe in windows.

[pglinkadssmall]

If you feel this article is helpful and interesting please spread a word about it to your friends and colleagues by sharing the article in Facebook or Twitter.

Share

You are always welcome to provide your comments and feedback from comment box.

[pgwriteforus]

[pgfeedback]

Related Articles

Author: Udhay

Share This Post On
468 ad
  • David Rodriguez

    Hello, thanks for the tutorial, its pretty useful. but im stuck with an error that i can’t solve, I hope you can help me “Class ‘Anonymous class derived from asynchttpresponsehandler must either be declared abstract or implement abstract method

    onFailure(int, Header[], byte[], Throwable) in AsyncHttpResponseHandler”

  • David Rodriguez

    I get the following error, can you help me?
    “Class ‘Anonymous class derived from asynchttpresponsehandler must
    either be declared abstract or implement abstract method
    onFailure(int, Header[], byte[], Throwable) in
    AsyncHttpResponseHandler”

Join now to get more access to our Android Tutorials

Join now to get more access to our Android Tutorials

Once you Join, you will receive Mail containing latest Android Tutorials once a month !!

I promise I wont spam you !!

You have Successfully Subscribed!

Pin It on Pinterest

Shares