Android upload image to server

Android upload image to server

Hey guyz in this post we will learn how to make a android upload image to server. We will be sending image as a string from the android app and that string will be decoded in our php script and uploaded to the server, We will be using Base64 encryption.
Prerequisite
In this post we will doing network request in android if your are not familiar with network request, Check out this post
JSON parsing in android using PHP and MySqli
Android JSON parser and populating in a listview



Demo of Android upload image to server

saveImage.php

This php file will handle the request send by our android app, decode the image and store it in the pic directory.

<?php
	$name = $_POST&#91;'name'&#93;; //image name
	$image = $_POST&#91;'image'&#93;; //image in string format

	//decode the image
	$decodedImage = base64_decode($image);

	//upload the image
	file_put_contents("pic/".$name.".jpg", $decodedImage);
?>

Project structure

In this project we have 2 java file MainActivity.java & Request.java

  1. MainActivity.java In this file we will have all the code to select a image,Encode a image, etc etc
  2. Request.java by this file we will send the encoded image & image name to saveImage.php file on the server and return the response to MainActivity.java

Android upload image to server

activity_main.xml

<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:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity"
                android:id="@+id/main">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:id="@+id/imageView"/>

    <Button
        android:layout_below="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Select Image"
        android:id="@+id/selectImage"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Upload Image"
        android:id="@+id/uploadImage"
        android:layout_alignBottom="@+id/selectImage"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>
</RelativeLayout>

Android upload image to server

MainActivity.java

Define global variable

We will define some global variables of Views

public class MainActivity extends Activity {
//define global views variable
public ImageView imageView;
public Button selectImage,
uploadImage;
public String SERVER = "http://192.168.1.2/co/storemanger/saveImage.php",
timestamp;

private static final String TAG = MainActivity.class.getSimpleName();

private static final int RESULT_SELECT_IMAGE = 1;

//others methods will come here
}

Instantiate views

We will instantiate ImageView and Button. Call selectImage() method when selectImage Button is pressed AND We will execute the Upload() Async task whenever the UploadImage button is pressed. (Chill both selectImage() and Upload() method are not yet defined)

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

//instantiate view
imageView = (ImageView) findViewById(R.id.imageView);
selectImage = (Button) findViewById(R.id.selectImage);
uploadImage = (Button) findViewById(R.id.uploadImage);

//when selectImage button is pressed
selectImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//call the function to select image from album
   selectImage();
}
});

//when uploadImage button is pressed
uploadImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
 //get image in bitmap format
Bitmap image = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
//execute the async task and upload the image to server
new Upload(image,"IMG_"+timestamp).execute();
}
});

}



selectImage() method

selectImage() method will open gallery/album so that user can select an image to upload. After selecting image onActivityResult() method will be called and we will check if the result was valid we will get the image URI and set it to the imageView and Generate a name for the image and store it in timestamp varaible

//function to select a image
    private void selectImage(){
        //open album to select image
        Intent gallaryIntent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(gallaryIntent, RESULT_SELECT_IMAGE);
    }

    /*
    * This function is called when we pick some image from the album
    * */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_SELECT_IMAGE && resultCode == RESULT_OK && data != null){
            //set the selected image to image variable
            Uri image = data.getData();
            imageView.setImageURI(image);

            //get the current timeStamp and strore that in the time Variable
            Long tsLong = System.currentTimeMillis() / 1000;
            timestamp = tsLong.toString();

            Toast.makeText(getApplicationContext(),timestamp,Toast.LENGTH_SHORT).show();
        }
    }

hashMapToUrl() method

this method will convert a hashMap into a Encoded URL that will be send to our saveImage.php file

private String hashMapToUrl(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for(Map.Entry<String, String> entry : params.entrySet()){
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }

Upload() AsyncTask

We will create a Upload Class which will extend AsyncTask class. Upload class will take a Bitmap and a Name(String), Then we will compress this image into JPEG and Encoded the image into Base64 String and send it to Request() Class

//async task to upload image

    private class Upload extends AsyncTask<Void,Void,String>{
        private Bitmap image;
        private String name;

        public Upload(Bitmap image,String name){
            this.image = image;
            this.name = name;
        }

        @Override
        protected String doInBackground(Void... params) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //compress the image to jpg format
            image.compress(Bitmap.CompressFormat.JPEG,100,byteArrayOutputStream);
            /*
            * encode image to base64 so that it can be picked by saveImage.php file
            * */

            String encodeImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(),Base64.DEFAULT);

            //generate hashMap to store encodedImage and the name

            HashMap<String,String> detail = new HashMap<>();
            detail.put("name", name);
            detail.put("image", encodeImage);

            try{
                //convert this HashMap to encodedUrl to send to php file

                String dataToSend = hashMapToUrl(detail);
                //make a Http request and send data to saveImage.php file

                String response = Request.post(SERVER,dataToSend);

                //return the response

                return response;

            }catch (Exception e){
                e.printStackTrace();
                Log.e(TAG,"ERROR  "+e);
                return null;
            }
        }



        @Override
        protected void onPostExecute(String s) {
            //show image uploaded
            Toast.makeText(getApplicationContext(),"Image Uploaded",Toast.LENGTH_SHORT).show();
        }
    }

MainActivity.java (Putting it all together)

package com.hackerkernel.imageupload;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;


public class MainActivity extends Activity {
    //define global views variable
    public ImageView imageView;
    public Button   selectImage,
                    uploadImage;
    public String SERVER = "http://192.168.1.2/co/storemanger/saveImage.php",
                    timestamp;

    private static final String TAG = MainActivity.class.getSimpleName();

    private static final int RESULT_SELECT_IMAGE = 1;

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

        //instantiate view
        imageView = (ImageView) findViewById(R.id.imageView);
        selectImage = (Button) findViewById(R.id.selectImage);
        uploadImage = (Button) findViewById(R.id.uploadImage);

        //when selectImage button is pressed
        selectImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //call the function to select image from album
                selectImage();
            }
        });

        //when uploadImage button is pressed
        uploadImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //get image in bitmap format
                Bitmap image = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
                //execute the async task and upload the image to server
                new Upload(image,"IMG_"+timestamp).execute();
            }
        });

    }

    //function to select a image
    private void selectImage(){
        //open album to select image
        Intent gallaryIntent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(gallaryIntent, RESULT_SELECT_IMAGE);
    }

    
    //This function is called when we pick some image from the album
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_SELECT_IMAGE && resultCode == RESULT_OK && data != null){
            //set the selected image to image variable
            Uri image = data.getData();
            imageView.setImageURI(image);

            //get the current timeStamp and strore that in the time Variable
            Long tsLong = System.currentTimeMillis() / 1000;
            timestamp = tsLong.toString();

            Toast.makeText(getApplicationContext(),timestamp,Toast.LENGTH_SHORT).show();
        }
    }

    private String hashMapToUrl(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for(Map.Entry<String, String> entry : params.entrySet()){
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }


    //async task to upload image
    private class Upload extends AsyncTask<Void,Void,String>{
        private Bitmap image;
        private String name;

        public Upload(Bitmap image,String name){
            this.image = image;
            this.name = name;
        }

        @Override
        protected String doInBackground(Void... params) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //compress the image to jpg format
            image.compress(Bitmap.CompressFormat.JPEG,100,byteArrayOutputStream);
            /*
            * encode image to base64 so that it can be picked by saveImage.php file
            * */
            String encodeImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(),Base64.DEFAULT);

            //generate hashMap to store encodedImage and the name
            HashMap<String,String> detail = new HashMap<>();
            detail.put("name", name);
            detail.put("image", encodeImage);

            try{
                //convert this HashMap to encodedUrl to send to php file
                String dataToSend = hashMapToUrl(detail);
                //make a Http request and send data to saveImage.php file
                String response = Request.post(SERVER,dataToSend);

                //return the response
                return response;

            }catch (Exception e){
                e.printStackTrace();
                Log.e(TAG,"ERROR  "+e);
                return null;
            }
        }



        @Override
        protected void onPostExecute(String s) {
            //show image uploaded
            Toast.makeText(getApplicationContext(),"Image Uploaded",Toast.LENGTH_SHORT).show();
        }
    }
}



Request.java

This file will be responsible to make a request to saveImage.php and get the response back(We are not giving any response in saveImage.php) We are just making a Toast message “Image Uploaded”

package com.hackerkernel.imageupload;

import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * class to make Http Request to the web
 */
public class Request {

    private static final String TAG = Request.class.getSimpleName();

    public static String post(String serverUrl,String dataToSend){
        try {
            URL url = new URL(serverUrl);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            //set timeout of 30 seconds
            con.setConnectTimeout(1000 * 30);
            con.setReadTimeout(1000 * 30);
            //method
            con.setRequestMethod("POST");
            con.setDoOutput(true);

            OutputStream os = con.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));

            //make request
            writer.write(dataToSend);
            writer.flush();
            writer.close();
            os.close();

            //get the response
            int responseCode = con.getResponseCode();

            if(responseCode == HttpURLConnection.HTTP_OK){
                //read the response
                StringBuilder sb = new StringBuilder();

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                String line;

                //loop through the response from the server
                while ((line = reader.readLine()) != null){
                    sb.append(line).append("\n");
                }

                //return the response
                return sb.toString();
            }else{
                Log.e(TAG,"ERROR - Invalid response code from server "+ responseCode);
                return null;
            }

        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"ERROR "+e);
            return null;
        }
    }
}

8 thoughts on “Android upload image to server”

  1. Hey, i tried using your code to try uploading an image file into the server remotely. The file seem to be uploaded onto the server, however the file seems to be corrupted. (0 bytes jpeg file named as ‘0.jpg’). Could it you please advice?

  2. If i use Django in place of php..will this code give correct result??
    i am having Django code that works correct when i run it with cmd.i want to run it with android app,as you did.

  3. everything work fine, image file is uploaded but
    1) named as [.jpg] – no name
    2) filesize is 0byte

    i didnt change any of your code (all copy & paste)
    may i know what went wrong? thanks

Leave a Reply

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