ANDROID – Upload an image to Server in Android Studio

By | April 25, 2011

Hi all,

In today’s tutorial I will show you how to send an image to server using POST method in ANDROID.

Uploading an image to server is a basic requirement in many of our application.
Sending data to server which is using a PHP Script is already explained in this example .
Now in this example I will show you how to send an image file.

For that first we have to read the file, put it in nameValuePairs and then send using HttpPost.

I have already shown you three other methods on uploading a file to server. If you want you can check these posts.

These are for downloading files from the server.

if you want to use the android using php and mysql
please check these posts.

Make easy money with infolinks

Add Permission

Add “android.permission.INTERNET” permission to your AndroidManifest.xml file.

Note

You need to add the below to your build.gradle since Apache library is deprecated by Google.

android {
useLibrary ‘org.apache.http.legacy’
}

build.gradle

Our Sample build.gradle may look like this.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.coderzheaven.uploadimage"
        minSdkVersion 21
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

android {
    useLibrary 'org.apache.http.legacy'
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
}

Layout

Our Sample XML layout will look like this.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.coderzheaven.uploadimage.MainActivity"
    tools:showIn="@layout/activity_main">

    <Button
        android:id="@+id/btnSelect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Select Image" />

    <ImageView
        android:id="@+id/imgView"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center" />

    <Button
        android:id="@+id/btnUpload"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Upload Image" />

    <TextView
        android:id="@+id/txtStatus"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:gravity="center"
        android:text=""
        android:textColor="@android:color/holo_green_light" />

</LinearLayout>

Make easy money with infolinks

Android Source Code

We will have a separate class for sending image.

Create a class named “UploadImageApacheHttp” and copy the below contents to it.
Before that, download the Base64 file from here which encodeBytes in Base64 Format.
Add it to your project.

File Upload Utility class

package com.coderzheaven.uploadimage;

import android.graphics.Bitmap;
import android.os.Handler;
import android.util.Log;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

public class UploadImageApacheHttp {

    public static final String TAG = "Upload Image Apache";

    public void doFileUpload(final String url, final Bitmap bmp, final Handler handler){

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {

                Log.i(TAG, "Starting Upload...");
                final ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("image", convertBitmapToString(bmp)));

                try {
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpPost httppost = new HttpPost(url);
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response = httpclient.execute(httppost);
                    String responseStr = EntityUtils.toString(response.getEntity());
                    Log.i(TAG, "doFileUpload Response : " + responseStr);
                    handler.sendEmptyMessage(1);
                } catch (Exception e) {
                    System.out.println("Error in http connection " + e.toString());
                    handler.sendEmptyMessage(0);
                }
            }
        });
        t.start();

    }

    public String convertBitmapToString(Bitmap bmp){
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 90, stream); //compress to which format you want.
        byte[] byte_arr = stream.toByteArray();
        String imageStr = Base64.encodeBytes(byte_arr);
        return imageStr;
    }
}

Make easy money with infolinks

Now the Activity that implements it.

Note : Make sure you select the image from the Gallery, because this demo is designed for selecting from Gallery.

MainActivity

package com.coderzheaven.uploadimage;

import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public static final String TAG = "Upload Image";

    // I am using my local server for uploading image, you should replace it with your server address
    public static final String UPLOAD_URL = "http://coderzheaven.com/sample_file_upload/upload_image.php";

    public static final String UPLOAD_KEY = "upload_image";

    private int PICK_IMAGE_REQUEST = 100;

    private Button btnSelect, btnUpload;
    private TextView txtStatus;

    private ImageView imgView;

    private Bitmap bitmap;

    private Uri filePath;

    private String selectedFilePath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        imgView = (ImageView) findViewById(R.id.imgView);
        btnSelect = (Button) findViewById(R.id.btnSelect);
        btnUpload = (Button) findViewById(R.id.btnUpload);
        txtStatus = (TextView) findViewById(R.id.txtStatus);

        btnSelect.setOnClickListener(this);
        btnUpload.setOnClickListener(this);

    }

    Handler handler = handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.i(TAG, "Handler " + msg.what);
            if (msg.what == 1) {
                txtStatus.setText("Upload Success");
            } else {
                txtStatus.setText("Upload Error");
            }
        }

    };

    private void showFileChooser() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE_REQUEST);
    }

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

        if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {

            filePath = data.getData();
            selectedFilePath = getPath(filePath);
            Log.i(TAG, " File path : " + selectedFilePath);
            try {
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
                imgView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public String getPath(Uri uri) {
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    private void uploadImage() {

        UploadImageApacheHttp uploadTask = new UploadImageApacheHttp();
        uploadTask.doFileUpload(UPLOAD_URL, bitmap, handler);

    }

    @Override
    public void onClick(View v) {
        if (v == btnSelect)
            showFileChooser();
        else {
            txtStatus.setText("Uploading Started...");
            uploadImage();
        }
    }
}


Note : You should do networks operations inside a thread only.
AND you cannot modify UI elements inside a UIThread only.

< Upload Image

Add Base64.java to your project

However you can put in your own package but don’t forget to change the package name otherwise you will get error.

Server part

Create a folder named Upload_image_ANDROID in your htdocs folder and inside that create a file named upload_image.php and copy this code into it.

I am saying the htdocs folder because I am using XAMPP. You change this according to your use.

< ?php
	$base=$_REQUEST['image'];
	 $binary=base64_decode($base);
	header('Content-Type: bitmap; charset=utf-8');
	$file = fopen('uploaded_image.jpg', 'wb');
	fwrite($file, $binary);
	fclose($file);
	echo 'Image upload complete!!, Please check your php file directory……';
?>

Now run your program and check the folder in which your php file resides.
Note: Make sure your server is running.
Here I am uploading the icon image itself.

If you want to upload another file in your SDCARD you have to change this line to give the exact path

   Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.icon);

For example if I have to upload a file residing in my SDCARD I would change the path like this.

 
   Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/android.jpg");

Source Code

You can download the complete Android studio Source Code from here.

Please send your comments to coderzheaven@gmail.com

101 thoughts on “ANDROID – Upload an image to Server in Android Studio

  1. Lucy

    Hi, Please could you tell me what i need to use for main.xml file, thankyou
    Lucy

    Reply
    1. James

      Hello Lucy..
      The main.xml file is for the interface. Since in this example it shows how to upload an image to server there is actually no need of an interface. You can put anything in the main.xml file. For example you can have a button which when clicked will upload the image, then put the code provided inside the button click, that’s all.
      You have to provide a layout for the setContentView() otherwise the program will not run.

      Reply
      1. Lucy

        Hi James,
        Thanks for the quick response, I confess, i’m an android newbie 🙁

        Would you be ever so kind as to help me out getting this to work, i guess all i need is the main.xml with a button that will upload the image, and the code to know that the button is there.

        Hope you can help, you can email me if you wish
        Thankyou
        Lucy

        Reply
        1. James

          @Lucy : Please wait for the answer we will contact you shortly.

          Reply
  2. Pingback: How to Download an image in ANDROID programatically? | Coderz Heaven

  3. idoudi

    Thank u .Nice Tuto:)
    I would like to uploade many images..
    How can I give a name for each image?

    Reply
  4. Pingback: How to Upload Multiple files in one request along with other string parameters in android? | Coderz Heaven

  5. Peter gabra

    Thanks a lot
    but i have problem with Base64.encodeBytes(byte_arr);
    it gives me error :S

    Reply
      1. andro

        Hi, I have the same problem with Peter gabra, and I have include the Base64.java in the src, could you help me to fixed it?

        Reply
        1. James

          Did you download the complete source code. Try changing the filename to something else and change accordingly in the main file.

          Reply
          1. andro

            Hi, thanks my problem solve now. I want to ask about base 64, because it just possible to send the image with small size, is there possible to send the image in big size to server using base64?
            thanks

  6. ski

    hei james nice tutorial. I am a newbie for android. May i have the full source code for this? and also i cannot find the “get picture from sd card gallery” thing like a picker in your code. so how do i pick the pic from my gallery?

    Reply
  7. Pravin

    Hi,,
    Nice post … But I have question what about image captured by Image and store it at Media.EXTERNAL_CONTENT_URI location.

    Thanks

    Reply
  8. LamprosGk

    It works fine, thanks.

    On the server the image gets “uploaded_image” filename.
    I’m sending to the server a file from my device’s sd card, it works ok (I have to downsize it though because I get out of memory error)
    I want the file name to be the same as the original, how can I do that??

    Reply
  9. LamprosGk

    Thanks James

    I’ve found out how to do it..
    (passed the file name in nameValuePairs to the php file

    Reply
  10. Rawan

    Thank you very very very much!!! This has been a tremendous help!
    I’d just like to add one small comment. I would suggest resizing the image before sending it the server because otherwise if the image is too big, it is very likely that you’ll get an out of memory exception.

    Bitmap resizedDishImage = Bitmap.createScaledBitmap(dishImage, 150, 150, false);

    Reply
  11. anthony

    Hello,

    I tried your code and it works fine with a local server, but with a remote server it doesn’t work 🙁
    Have you an idea why ?

    Reply
    1. James

      No, it works perfectly with any server. Please check your server address or anyother parameters you are sending.

      Reply
  12. juan

    Hello,

    Very nice post. Is there a way I can do this using a web app instead of an installed app?

    thank you!

    Reply
    1. James

      Sorry Hari that was problem with my syntax highlighter, please check the post again.

      Reply
  13. hari

    Hello James,

    Thanks for the reply. Its working very fine. Thanks man

    Reply
  14. Chris

    Hi,

    the encodeBytes method is giving me an error saying “encodedBytes is undefined for type Base64” . i have downloaded the Base64 class, and inserted it into my project..could you please help me????

    Reply
  15. diego

    hey this “Bitmap bitmap = BitmapFactory.decodeFile(“/sdcard/mypic.jpg”);” does not work, do you have any idea why?

    Reply
    1. diego

      but if it works whrn i used Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.icon);

      Reply
  16. hariprasad

    hi i run ur apps successfully…result also displayed successfully.Image upload complete!!, Please check your php file directory……But my doubt is where is uploaded file is saved..how is know the above image is successfully uploaded…where i see the image after successful completion…

    Reply
    1. James

      The uploaded file will be saved in the uploads directory in your server where your php file is located.

      Reply
      1. Johnson Daniel

        I can’t view the uploaded image, do I need to change anything in the php code, if so pls tell what are the things to be changed , Thank you

        Reply
  17. chand

    Wooow… thanku so much. It works great. And how can I upload an image which is captured? where I have modify in this code…?

    Reply
  18. Ganesh

    hi!
    can anyone suggest me an alternative to above server side phpscript.
    Any help will be appreciated..

    Reply
  19. sunil

    hi,

    its so excellent tutorial…..i m getting a problem……i want to upload an image on jboss server……what i has to bb done on jboss server……what code i hv to write there…….plz any one guide me………..

    Reply
  20. Steven

    hi guys
    can i ask qustion?
    did i need to write code to start xampp for android?
    because i didnt sure cellphone can work?

    Reply
    1. James

      No Steven, there is no connection between starting the xampp server and android. if your http request have to reach the server, xampp should be on and running.

      Reply
  21. Steven

    Hi James
    I am Sorry ,Could you tell me
    I just need to put the upload_image.php this file to htddocs folder in xampp
    Did I need to set any about website?

    Reply
    1. Steven

      oh I know where is my problem.
      if you want to connection and run in Android cellphone.
      Your IP must be entity.
      otherwise you can,t connection, this is message for dont understand other guys.

      Reply
    2. James

      No you can test it locally. The post describes how to work with it locally. If you have a server then put the file in the right place and just change the UR.

      Reply
  22. Jigar

    i am able to sleect both the files..but when i hit StartUpload button, the upload process dialog box shows for 1 sec and then the error message is shown saying “Unfortunately the process pack.coderzheaven” has stopped.
    i have added the internet permission in manifest also.. my Wamp server is On..also i have used localhost instead of 10.0.2.2 in the code.. Can u plz tell me where i am going wrong ?

    Reply
    1. James

      what is the reason for the error in the logcat? please check that and paste it here.

      Reply
  23. Kyle

    package pack.coderzheaven;

    what is this thing ?
    and how come i dint see any package from the coding above ?
    example like : package com.sample.testing

    Reply
    1. Kyle

      opps sorry, when i see the coding above the package seems to be appear as something like this,
      span id=”IL_AD1″ class=”IL_AD” package /span pack.coderzheaven;

      i only see it as “package pack.coderzheaven;’
      after i dropped comment..

      Reply
      1. James

        Sorry Kyle, that was the problem with the syntax highlighter.

        Reply
    1. James

      That’s the problem with you server. Check the permissions.

      Reply
  24. Alvin tan

    How to download pictures that i have just uploaded in this localserver i tried putting back in for example ‘http://192.168.1.3/Upload_image_ANDROID/upload_image.php’ where i presume i uploaded but didnt work

    Reply
  25. Saranya

    I am getting error as null. Bitmap.compress is not working.Can you plz help me..

    Reply
  26. nev

    echo ‘Image upload complete!!, Please check your php file directory……’;

    sir i have a problem.. how can we view the image($file) in our page. because u can view the image only in the php..

    this is my code

    echo ‘$file’ …

    code is not workng

    Reply
  27. mungaih

    I have an app that captures an image and displays it.how do I upload the captured image?thanks

    Reply
    1. James

      You will get the image inside onActivityResult() function. From there save it in a temporary file and then upload using the above example.

      Reply
  28. santosh

    Great tutorial 🙂 i am getting ERROR null(showing in toast).Plz help me out…….

    Reply
    1. Tyson

      So I am …
      I have traced that the application stopped at the following statement.
      HttpResponse response = httpclient.execute(httppost);

      The httppost information is correct. Any idea?

      Thanks a lot!

      Reply
  29. Pingback: Best way to store camera clicked pics on android? : Android Community - For Application Development

  30. Pingback: how to send photo from android device to FTP server : Android Community - For Application Development

  31. sohyal

    setContentView(R.layout.main);
    I am getting error on this line and all other lines where R is present
    There is R.java file in my gen folder i always get error on this please help!

    Reply
    1. Amina

      setContentView(R.layout.main);
      you have to chage “main ” according to the name of your xml file .for example : activity_main.xml ,..

      Reply
  32. Imran62

    After Uploading a file in mnt/sd card to mySQL ,Dialog box is still being uploading..Do I need to remove files in my Gallery (Emulator)???I am not getting Output

    Reply
  33. Josh

    great tutorial! but I have a stupid question..
    “How does the server know where this image uploaded to?”
    I added in the SQL statement for tables and columns. good news is the image string had successfully changed to the image path(eg. sdcard/…../sample.png)

    but bad news is.. my server’s image folder does not contain that image that i just uploaded.. may i know which code did i missed out? or what went wrong?

    no error code given.. only success all the way..

    Reply
    1. James

      Server will not know where to upload the files. The folder to upload the file is written by you in the PHP file.

      Reply
      1. Johnson Daniel

        I can’t view the uploaded image, do I need to change anything in the php code, if so pls tell what are the things to be changed , Thank you

        Reply
          1. Johnson Daniel

            pls tell me in which line should we provide the upload location

            I haven’t changed anything in this code, where should I change, Thank you

  34. Pingback: PHP to ASP.NET code migration | BlogoSfera

  35. segen

    I already have the Internet Permission in manifest.Always i try to upload the file i get:
    07-23 14:46:12.681: I/System.out(16675): Error in http connection android.os.NetworkOnMainThreadException

    Sometimes make a jpg file in server with the name but with 0 size.
    About this line: HttpResponse response = httpclient.execute(httppost);
    Wait for the response?or make a threat?
    It can be the size of the pic to upload?there is a limit?

    I tried with small icon pic but nothing.

    Reply
    1. James

      Hello segen

      Do the uploading inside a thread, because on newer versions of android it will not allow network operations to be done in the main thread. Update UI elements inside the thread from another runonUIThread only. Otherwise the application will crash.

      I have made an edit to reflect the changes.

      Reply
  36. Abhishek

    Nice work man, Thanks, This is exactly I was looking for. I want to save the file in the root folder but it is toasting the message permission denied. I guess I need to be the super user. How can we do it? Do we need to change in Android or the PHP code.

    One more question I need to take pictures from camera and send it without saving it in the phone memory location. I have a code running which takes pictures every 10 Sec but I need to integrate with this, So instead of using BitmapFactory.decodeResource(getResources(),R.drawable.icon); what shall I use?

    Regards
    Abhishek

    Reply
  37. D. Hoover

    Great tutorial, but I get an error on line 33; The method encodeBytes(byte[]) is undefined for the type Base64 and I have the Base64.java in my package. Can you help me out?

    Reply
  38. bilal

    Please tell me how can i assign a variable name to my image file which is being uploaded?

    Reply
  39. bilal

    please tell me how can i change the name of my image file which is being uploade?

    Reply
  40. marco

    Hi James, do you have the code to retrieve the image and display it in a listview?

    Reply
  41. Tyler

    Hello, I’m having a little trouble with this program. It is with this line:
    HttpResponse response = httpclient.execute(httppost);
    it says:
    Description Resource Path Location Type
    Syntax error on tokens, TypeArgumentList1 expected instead NewSpotActivity.java /AndroidConnectingToPhpMySQL/src/com/example/androidhive line 142 Java Problem

    Reply
  42. Ryan Putranda Kristianto

    Can you show me the source code of main.xml layout of project you use?

    Reply
  43. Amina

    great tutorial and it works !! thank you James.
    And i have a question ,well i’m triying to follow the speed of the upload .I already did it with the download and it worked .
    while ((count = input.read(data)) != -1) {
    total += count;
    long endtTime = System.currentTimeMillis();
    long passed;
    passedTime =endtTime – startTotalTime;
    // publishing the progress….
    // After this onProgressUpdate will be called
    publishProgress(“”+(int)((total*100)/lenghtOfFile));
    Log.i(“log_lenghtOfFile”,lenghtOfFile+”” );
    Log.i(“log_total”,total+”” );
    Log.i(“log_ourcentage”,(int)((total*100)/lenghtOfFile)+”” );
    Log.i(“log_passed_time”,passedTime +”” );

    }
    but i had a problem with the uploading i need to get :
    t= 10 s uploded data =10byte /total data
    t =45 uploaded data =150byte/total data (for example )
    Ididn’t found where i could follow the rate of uploading ,i tryed to do that in base64,but it didn’t work.
    please if you have an idea help me.

    Reply
  44. dhiraj

    hey i m new to android development, i want to do my final year project based on this. can u plz send me complete code with main.xml and menifest.xml.. plzz mail me the code as soon as possible. ur help is very iportant for me. plz

    Reply
  45. suhad

    Thank you very much………thanks a loooooooooooooot..
    God bless you

    Reply
  46. Pingback: how to send the image in an ImageView to a php server? - PHP Solutions - Developers Q & A

  47. Akshat

    is it necessary to use

    header('Content-Type: bitmap; charset=utf-8');

    or can we remove that?

    Reply
  48. Will

    Silly me.. I forgot to change the request tag in the PHP script. Working perfect now. Thanks for this. It’s just what I needed. Simple enough for me to understand and a good starting point. Next I will try to assign a specific file name, put the file name in my database, and also retrieve the image back to my list view.

    Reply
  49. Tufail

    Notice: Undefined index: image in C:\wamp\www\Upload_image_ANDROID\upload_image.php on line 2

    i found this error while running server part code and i also run this code on wamp

    Reply
  50. harsha

    Hi how to upload both image file and string details from android to server using post methode with basic namevalue pairs can u give some sample code please.

    Reply
    1. James

      You can simply copy paste the code into an Activity and it will work.

      Reply
  51. faizi

    excellent tutorial have to do a lot of changes but at the end code works….
    if you don’t the errors then follow these steps..
    1
    permission (internet)(read external storage) in manifest file
    2
    download base64 file to your project package where image file is placed
    3
    then some exceptions that android studio will handle as well
    4
    thanks to JAMES nice tutorial…..
    5
    setContentView(here put you xml file just and rest is fine…just run the code now and image will be uploaded to the website through app…:)….. )
    6
    some may have errors regarding gradle build
    use sdk min 8 max 21

    Reply
  52. Gabriel Albasini

    This is great, Thank you!! Could you please post both php files??

    Reply

Leave a Reply

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