Welcome to Android Upload image To Server (PHP-MySQL) Tutorial.
There are a total of six different ways to upload image to the server as per the following.
1. Android Upload Image To Server Using Volley
2. Android Upload Image To Server Using Retrofit
3. Upload Image To Server In Android Using Multipart volley
4. Upload Image To Server In Android Using Multipart Retrofit2
1. Android Upload Image To Server Using Volley
In this tutorial, we will upload the image to server using volley in android.
We will use PHP as a server script and MySQL as the server database.
Using volley, we can upload the image into the Base64String format to the remote server.
First, we will convert the image into the Base64String format and then we will upload it using PHP web service.
This process simplifies the process of sending the image to the remote server.
Volley uses very few lines of code to complete this task, which reduces the complexity.
View Volley Upload Image
PHP Script
Make a new PHP file and it’s name is config.php
Following is it’s code block
<?php $host="localhost"; $user="your username"; $password="your password"; $db = "your db name"; $con = mysqli_connect($host,$user,$password,$db); // Check connection if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }else{ //echo "Connect"; } ?>
Following is the code for the PHP script named uploadVolley.php file
<?php include_once("config.php"); $json = json_decode(file_get_contents('php://input'),true); $name = $json["name"]; //within square bracket should be same as Utils.imageName & Utils.image $image = $json["image"]; $response = array(); $decodedImage = base64_decode("$image"); $return = file_put_contents("uploadedFiles/".$name.".JPG", $decodedImage); if($return !== false){ $response['success'] = 1; $response['message'] = "Image Uploaded Successfully"; }else{ $response['success'] = 0; $response['message'] = "Image Uploaded Failed"; } echo json_encode($response); ?>
Step 1. Add Required Permissions
We need to have some permissions in this tutorial.
Add the below source code in AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Three permissions are there: internet, read internal storage and write internal storage.
Among them, internet is normal permission but we need to ask runtime permissions for read and write external storage.
We will write the code for runtime permissions in MainActivity.java file later.
Step 2. Needed dependencies
We require following dependencies
implementation 'com.android.volley:volley:1.1.1' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.karumi:dexter:5.0.0'
Add above three lines in build.gradle(Module: app) file of your project.
First line will enable us to use the volley library.
Second will add the classes of picasso library to load the image from URL.
Third line will help to ask for runtime permissions with dexter library.
Step 3. activity_main.xml
Now let us create the activity_main.xml file.
First of all, write down the below coding lines in activity_main.xml file.
<?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="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Select Image and upload to server" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Below image is uploaded to server" android:layout_marginTop="5dp" android:textSize="23sp" android:gravity="center" android:textColor="#000"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" android:id="@+id/iv"/> </LinearLayout>
I have taken one button, one textview and one Imageview in the above file.
When the user clicks the button, he will be asked to select the image.
Textview is telling the user that below compiler upload the image below image.
ImageView holds that uploaded image.
Step 4. Writing Main Activity
In your MainActivity.java file, write down the following coding lines
import android.Manifest; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; 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 com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.Volley; import com.karumi.dexter.Dexter; import com.karumi.dexter.MultiplePermissionsReport; import com.karumi.dexter.PermissionToken; import com.karumi.dexter.listener.DexterError; import com.karumi.dexter.listener.PermissionRequest; import com.karumi.dexter.listener.PermissionRequestErrorListener; import com.karumi.dexter.listener.multi.MultiplePermissionsListener; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Calendar; import java.util.List; public class MainActivity extends AppCompatActivity { private Button btn; private ImageView imageView; private final int GALLERY = 1; private String upload_URL = "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadVolley.php"; JSONObject jsonObject; RequestQueue rQueue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestMultiplePermissions(); btn = findViewById(R.id.btn); imageView = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); imageView.setImageBitmap(bitmap); uploadImage(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } } private void uploadImage(Bitmap bitmap){ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); try { jsonObject = new JSONObject(); String imgname = String.valueOf(Calendar.getInstance().getTimeInMillis()); jsonObject.put("name", imgname); // Log.e("Image name", etxtUpload.getText().toString().trim()); jsonObject.put("image", encodedImage); // jsonObject.put("aa", "aa"); } catch (JSONException e) { Log.e("JSONObject Here", e.toString()); } JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, upload_URL, jsonObject, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { Log.e("aaaaaaa", jsonObject.toString()); rQueue.getCache().clear(); Toast.makeText(getApplication(), "Image Uploaded Successfully", Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Log.e("aaaaaaa", volleyError.toString()); } }); rQueue = Volley.newRequestQueue(MainActivity.this); rQueue.add(jsonObjectRequest); } private void requestMultiplePermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); } }
Running through above Code
Consider the below coding lines
private final int GALLERY = 1; private String upload_URL = "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadVolley.php"; JSONObject jsonObject; RequestQueue rQueue;
First line is making a final integer variable named GALLERY.
Value of GALLERY is constant that means it’s value can not be changed.
Second line is defining a String variable which holds the URL from which we will call the web service.
This web service will get the Image as a parameter and will add the image to the server.
Third line is making an object of the JSONObject class.
Final line is making an object of RequestQueue class.
In onCreate() method, compiler is calling requestMultiplePermissions() method.
Code structure for requestMultiplePermissions() method is as the below
private void requestMultiplePermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); }
This method is helping us to ask for runtime permissions to the user.
Compiler will use the classes and methods of the dexter library in this method.
Dexter library simplifies the whole scenario of runtime permissions.
We will ask for Read and Write external storage permissions in this method.
Now read the following coding lines
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } });
Compiler will execute the above code when the user clicks on the button.
Here, compiler will first create one Intent.
This intent will lead the user to new screen.
In this screen, system will showcase all the images present in the gallery.
Now user have to select one image from this screen. When he clicks on OK button after choosing the image, compiler will run the onActivityResult() method.
Following is the code block for onActivityResult() method.
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); imageView.setImageBitmap(bitmap); uploadImage(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } }
Here, compiler will check if user have selected one image or not.
if the value of requestCode is equals to the GALLERY (1) variable then compiler will enter into if(requestCode == GALLERY) condition.
Now, system will first collect the URI from the data passes in this onActivityResult() method.
Then compiler will create the Bitmap from this URI.
After that, compiler will set that bitmap into the imageview.
And then it will call the uploadImage() method.
Coding lines for uploadImage() method is as the following
private void uploadImage(Bitmap bitmap){ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); try { jsonObject = new JSONObject(); String imgname = String.valueOf(Calendar.getInstance().getTimeInMillis()); jsonObject.put("name", imgname); // Log.e("Image name", etxtUpload.getText().toString().trim()); jsonObject.put("image", encodedImage); // jsonObject.put("aa", "aa"); } catch (JSONException e) { Log.e("JSONObject Here", e.toString()); } JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, upload_URL, jsonObject, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { Log.e("aaaaaaa", jsonObject.toString()); rQueue.getCache().clear(); Toast.makeText(getApplication(), "Image Uploaded Successfully", Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Log.e("aaaaaaa", volleyError.toString()); } }); rQueue = Volley.newRequestQueue(MainActivity.this); rQueue.add(jsonObjectRequest); }
First three lines will convert the image bitmap into Base64 string format.
Then, compiler will initialize the jsonObject.
After that, compiler will create the current time in milliseconds and sets it in string variable.
This string variable will be the unique name of the image.
Following two lines are the parameters of the web service
jsonObject.put("name", imgname); // Log.e("Image name", etxtUpload.getText().toString().trim()); jsonObject.put("image", encodedImage);
First is the name of the image and the second is the image itself in BASE64 String.
Then compiler will create the object of JsonObjectRequest class and will call the web service.
onResponse() method will be called when the web service gives any response in the JSON format.
In the onResponse() method, compiler will clear the Volley cache.
2. Android Upload Image To Server Using Retrofit
Hello and welcome to Android Upload Image To Server Using Retrofit Example.
In this tutorial, you will learn how to upload image using retrofit android to PHP MySQL server.
Retrofit will take care about http calls and data transaction between android and remote server.
We need to write one PHP script that will accept the image into Base64String format.
See the Video
JSON from Server
See the below image. It is the json we are getting from the server after successful upload of image.
PHP Section
Make a new file and add the below code lines in it. Name of this file should be uploadRetrofit.php
<?php include_once("config.php"); //$json = json_decode(file_get_contents('php://input'),true); $name = $_POST["name"]; //within square bracket should be same as Utils.imageName & Utils.image $image = $_POST["image"]; //$image = substr(explode(";",$image)[1], 7); $response = array(); $decodedImage = base64_decode("$image"); $return = file_put_contents("uploadedFiles/".$name.".JPG", $decodedImage); if($return !== false){ $response['success'] = 1; $response['message'] = "Image Uploaded Successfully with Retrofit"; }else{ $response['success'] = 0; $response['message'] = "Image Uploaded Failed"; } echo json_encode($response); ?>
Code for config.php is like the following
<?php $host="localhost"; $user="your username"; $password="your password"; $db = "your db name"; $con = mysqli_connect($host,$user,$password,$db); // Check connection if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }else{ //echo "Connect"; } ?>
Now create a new project in android studio.
Step 1. Basic Permissions
In this tutorial we need some permissions and also need to add three dependencies in gradle file.
So add the following lines in ANDROIDMANIFEST.xml file.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
First line is about internet permission and other two are for read and to write files on external storage.
Now in your build.gradle(Module: app) file, add the below lines
implementation 'com.karumi:dexter:5.0.0' implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'
Here, first line will give us the right to use the dexter library in our project. This library will help us to simplify the runtime permissions process.
Second line will enable us to use retrofit library and third one will use scalar to convert JSON response into string format.
Step 2. Useful Interface
Make a new java class and give it a name like ImageInterface.java
Source code for ImageInterface.java is as the following
import retrofit2.Call; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface ImageInterface { String IMAGEURL = "https://demonuts.com/Demonuts/JsonTest/Tennis/"; @FormUrlEncoded @POST("uploadRetrofit.php") Call<String> getUserLogin( @Field("name") String name, @Field("image") String image ); }
A string variable is containing the URL of the web service.
@POST(“uploadRetrofit.php”) is the name of the php script that we have already created.
getUserLogin() method have two parameters. First one is the name of the image and second one is the image it self into Base64 String format.
Step 3. Final Code Lines
Now we are just left with activity_main.xml and MainActivity.java file
In your activity_main.xml file, write down the below code block
<?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="match_parent" android:layout_height="match_parent" android:background="#18cae6" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Select Image and upload to server" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Below image is uploaded to server using Retrofit" android:layout_marginTop="5dp" android:textSize="23sp" android:gravity="center" android:textColor="#000"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" android:id="@+id/iv"/> </LinearLayout>
Above holds one Button, one text view and one image view.
When the user clicks the button, system will show him all the images of galley, from where he need to select any one.
Text view is saying like “below image is uploaded using retrofit.”
We will set the image in the image view which we will upload on the php mysql server.
Now in MainActivity.java file, fill the following code structure
import android.Manifest; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; 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 com.karumi.dexter.Dexter; import com.karumi.dexter.MultiplePermissionsReport; import com.karumi.dexter.PermissionToken; import com.karumi.dexter.listener.DexterError; import com.karumi.dexter.listener.PermissionRequest; import com.karumi.dexter.listener.PermissionRequestErrorListener; import com.karumi.dexter.listener.multi.MultiplePermissionsListener; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Calendar; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.scalars.ScalarsConverterFactory; public class MainActivity extends AppCompatActivity { private Button btn; private ImageView imageView; private final int GALLERY = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestPermissions(); btn = findViewById(R.id.btn); imageView = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); imageView.setImageBitmap(bitmap); uploadImage(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } } private void uploadImage(Bitmap bitmap){ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); String imgname = String.valueOf(Calendar.getInstance().getTimeInMillis()); Retrofit retrofit = new Retrofit.Builder() .baseUrl(ImageInterface.IMAGEURL) .addConverterFactory(ScalarsConverterFactory.create()) .build(); ImageInterface api = retrofit.create(ImageInterface.class); Log.d("helloo",encodedImage +" >>"+imgname); Log.d("imggggg"," >>"+imgname); Call<String> call = api.getUserLogin(imgname,encodedImage); call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.i("Responsestring", response.body().toString()); //Toast.makeText() if (response.isSuccessful()) { if (response.body() != null) { Log.i("onSuccessimg", response.body().toString()); Toast.makeText(MainActivity.this, "Image Uploaded Successfully!!", Toast.LENGTH_SHORT).show(); } else { Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show(); } } } @Override public void onFailure(Call<String> call, Throwable t) { } }); } private void requestPermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); } }
Looking at above code
In the onCreate() method, first of all compiler will call requestPermissions() method.
Below are the writings for requestPermissions() method.
private void requestPermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); }
This method will ask for runtime permissions to the user. It will ask for read and write permissions.
We have also added internet permission in manifest file, but it is normal permission, so need to ask it here again.
Now, compiler will again go to onCreate() method. Below code will be run when the user clicks the button.
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } });
Compiler will create one intent when the user clicks the button. This intent would be for ACTION_PICK. Meaning is that it will allow user to select image.
When the user selects the image, compiler will call onActivityResult() method.
Following is the code lines for onActivityResult() method,
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); imageView.setImageBitmap(bitmap); uploadImage(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } }
Compiler will first get the URI of the image from the selected data.
Then it will create the bitmap of the image.
After this, it will set the bitmap into the image view.
Finally, it will call the uploadImage() method.
Below is the code snippet for uploadImage() method.
private void uploadImage(Bitmap bitmap){ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); String imgname = String.valueOf(Calendar.getInstance().getTimeInMillis()); Retrofit retrofit = new Retrofit.Builder() .baseUrl(ImageInterface.IMAGEURL) .addConverterFactory(ScalarsConverterFactory.create()) .build(); ImageInterface api = retrofit.create(ImageInterface.class); Log.d("helloo",encodedImage +" >>"+imgname); Log.d("imggggg"," >>"+imgname); Call<String> call = api.getUserLogin(imgname,encodedImage); call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.i("Responsestring", response.body().toString()); //Toast.makeText() if (response.isSuccessful()) { if (response.body() != null) { Log.i("onSuccessimg", response.body().toString()); Toast.makeText(MainActivity.this, "Image Uploaded Successfully!!", Toast.LENGTH_SHORT).show(); } else { Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show(); } } } @Override public void onFailure(Call<String> call, Throwable t) { } }); }
Compiler will get the bitmap into the parameter of this method.
Using this bitmap, it will convert the image into the Base64 string format. A string variable “encodedImage” holds this base64 value.
A variable imgname will have the value of current millisecond as the name of the image in string format.
After this, compiler will create the object of the Retrofit class. Here, .baseUrl(Imagenterface.IMGURL) will give the URL to the retrofit.
api.getUserLogin(imgname, encodedImage) will make the http call to the remote server.
When the compiler gets the JSON response, it will call the onResponse() method.
Inside onResponse() method, system will show one toast.
3. Upload Image To Server In Android Using Multipart volley
Upload image To Server In Android Using Multipart Volley Tutorial is here.
We will upload image using multipart volley from android device.
There are two options to upload the image to the server with volley.
- Convert Image to Base64 and then send to server.
- Upload image directly using multipart
I have used the second option in this tutorial.
Multipart allows us to send the image in it’s original format.
With volley, this complex task becomes much easier with few coding lines.
See Multipart Volley
PHP Web Service
Below is the code block of the PHP web service which will upload the image to the server.
Name of this file is uploadfile.php
<?php if($_SERVER['REQUEST_METHOD']=='POST'){ // echo $_SERVER["DOCUMENT_ROOT"]; // /home1/demonuts/public_html //including the database connection file include_once("config.php"); //$_FILES['image']['name'] give original name from parameter where 'image' == parametername eg. city.jpg //$_FILES['image']['tmp_name'] temporary system generated name $originalImgName= $_FILES['filename']['name']; $tempName= $_FILES['filename']['tmp_name']; $folder="uploadedFiles/"; $url = "http://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName; if(move_uploaded_file($tempName,$folder.$originalImgName)){ $query = "INSERT INTO upload_image_video (pathToFile) VALUES ('$url')"; if(mysqli_query($con,$query)){ $query= "SELECT * FROM upload_image_video WHERE pathToFile='$url'"; $result= mysqli_query($con, $query); $emparray = array(); if(mysqli_num_rows($result) > 0){ while ($row = mysqli_fetch_assoc($result)) { $emparray[] = $row; } echo json_encode(array( "status" => "true","message" => "Successfully file added!" , "data" => $emparray) ); }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } //echo "moved to ".$url; }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } } ?>
Step 1. Manifest changes
We need few permissions in this tutorial to accomplish our goal.
Add the below code lines in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Now we need to ask for runtime permissions for second and third line.
- We will do this task MainActivity.java class later.
Internet is normal permission so no need for runtime version of it.
Step 2. Writing gradle file
Let us add some dependencies that will help us in this tutorial.
Add the following code in build.gradle(Module: app) file
implementation 'com.android.volley:volley:1.1.1' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.karumi:dexter:5.0.0'
- First dependency is for volley library. It will allow us to use volley classes in our project.
- Second is for picasso. We will load the imahe from URL using picasso library.
- Third one is for dexter which is the library for runtime permissions.
Step 3. Multipart Class
Create a new JAVA class and give it a name VolleyMultipartRequest.java
Code structure for VolleyMultipartRequest.java is as the below
import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.HttpHeaderParser; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; public class VolleyMultipartRequest extends Request<NetworkResponse> { private final String twoHyphens = "--"; private final String lineEnd = "\r\n"; private final String boundary = "apiclient-" + System.currentTimeMillis(); private Response.Listener<NetworkResponse> mListener; private Response.ErrorListener mErrorListener; private Map<String, String> mHeaders; public VolleyMultipartRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { super(method, url, errorListener); this.mListener = listener; this.mErrorListener = errorListener; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return (mHeaders != null) ? mHeaders : super.getHeaders(); } @Override public String getBodyContentType() { return "multipart/form-data;boundary=" + boundary; } @Override public byte[] getBody() throws AuthFailureError { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); try { // populate text payload Map<String, String> params = getParams(); if (params != null && params.size() > 0) { textParse(dos, params, getParamsEncoding()); } // populate data byte payload Map<String, DataPart> data = getByteData(); if (data != null && data.size() > 0) { dataParse(dos, data); } // close multipart form data after text and file data dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); return bos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Custom method handle data payload. * * @return Map data part label with data byte * @throws AuthFailureError */ protected Map<String, DataPart> getByteData() throws AuthFailureError { return null; } @Override protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) { try { return Response.success( response, HttpHeaderParser.parseCacheHeaders(response)); } catch (Exception e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(NetworkResponse response) { mListener.onResponse(response); } @Override public void deliverError(VolleyError error) { mErrorListener.onErrorResponse(error); } /** * Parse string map into data output stream by key and value. * * @param dataOutputStream data output stream handle string parsing * @param params string inputs collection * @param encoding encode the inputs, default UTF-8 * @throws IOException */ private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException { try { for (Map.Entry<String, String> entry : params.entrySet()) { buildTextPart(dataOutputStream, entry.getKey(), entry.getValue()); } } catch (UnsupportedEncodingException uee) { throw new RuntimeException("Encoding not supported: " + encoding, uee); } } /** * Parse data into data output stream. * * @param dataOutputStream data output stream handle file attachment * @param data loop through data * @throws IOException */ private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException { for (Map.Entry<String, DataPart> entry : data.entrySet()) { buildDataPart(dataOutputStream, entry.getValue(), entry.getKey()); } } /** * Write string data into header and data output stream. * * @param dataOutputStream data output stream handle string parsing * @param parameterName name of input * @param parameterValue value of input * @throws IOException */ private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException { dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd); dataOutputStream.writeBytes(lineEnd); dataOutputStream.writeBytes(parameterValue + lineEnd); } /** * Write data file into header and data output stream. * * @param dataOutputStream data output stream handle data parsing * @param dataFile data byte as DataPart from collection * @param inputName name of data input * @throws IOException */ private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException { dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd); if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) { dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd); } dataOutputStream.writeBytes(lineEnd); ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent()); int bytesAvailable = fileInputStream.available(); int maxBufferSize = 1024 * 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); byte[] buffer = new byte[bufferSize]; int bytesRead = fileInputStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { dataOutputStream.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } dataOutputStream.writeBytes(lineEnd); } class DataPart { private String fileName; private byte[] content; private String type; public DataPart() { } DataPart(String name, byte[] data) { fileName = name; content = data; } String getFileName() { return fileName; } byte[] getContent() { return content; } String getType() { return type; } } }
- This class will help us to make http calls using volley library.
- We will create object of this class whenever we want to make volley http calls.
- Methods of this class will also play important part.
You do not need to make any change in this class. Just keep it as it is.
Step 4. Main Updation
Let us make changes in activity_main.xml and MainActivity.java files.
Make sure the code of activity_main.xml looks same as the below one
<?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="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:background="@color/colorAccent" android:textColor="#fff" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Select Image and upload to server" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Below image is uploaded to server" android:layout_marginTop="5dp" android:textSize="23sp" android:gravity="center" android:textColor="#000"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" android:id="@+id/iv"/> </LinearLayout>
There are three widgets in the above file.
One button, one textview and one imageview.
When the user clicks on the button, a screen will be open from which he can select the image.
Textview is saying that the image in the imageview is uploaded to the server.
Imageview will have the preview of the uploaded image.
Now in the MainActivity.java file, write down the following source code
import android.Manifest; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import com.android.volley.AuthFailureError; import com.android.volley.DefaultRetryPolicy; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.Volley; import com.karumi.dexter.Dexter; import com.karumi.dexter.MultiplePermissionsReport; import com.karumi.dexter.PermissionToken; import com.karumi.dexter.listener.DexterError; import com.karumi.dexter.listener.PermissionRequest; import com.karumi.dexter.listener.PermissionRequestErrorListener; import com.karumi.dexter.listener.multi.MultiplePermissionsListener; import com.squareup.picasso.Picasso; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { private Button btn; private ImageView imageView; private final int GALLERY = 1; private String upload_URL = "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php?"; private RequestQueue rQueue; private ArrayList<HashMap<String, String>> arraylist; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestMultiplePermissions(); btn = findViewById(R.id.btn); imageView = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); // imageView.setImageBitmap(bitmap); uploadImage(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } } private void uploadImage(final Bitmap bitmap){ VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, upload_URL, new Response.Listener<NetworkResponse>() { @Override public void onResponse(NetworkResponse response) { Log.d("ressssssoo",new String(response.data)); rQueue.getCache().clear(); try { JSONObject jsonObject = new JSONObject(new String(response.data)); Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show(); jsonObject.toString().replace("\\\\",""); if (jsonObject.getString("status").equals("true")) { arraylist = new ArrayList<HashMap<String, String>>(); JSONArray dataArray = jsonObject.getJSONArray("data"); String url = ""; for (int i = 0; i < dataArray.length(); i++) { JSONObject dataobj = dataArray.getJSONObject(i); url = dataobj.optString("pathToFile"); } Picasso.get().load(url).into(imageView); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show(); } }) { /* * If you want to add more parameters with the image * you can do it here * here we have only one parameter with the image * which is tags * */ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> params = new HashMap<>(); // params.put("tags", "ccccc"); add string parameters return params; } /* *pass files using below method * */ @Override protected Map<String, DataPart> getByteData() { Map<String, DataPart> params = new HashMap<>(); long imagename = System.currentTimeMillis(); params.put("filename", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap))); return params; } }; volleyMultipartRequest.setRetryPolicy(new DefaultRetryPolicy( 0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); rQueue = Volley.newRequestQueue(MainActivity.this); rQueue.add(volleyMultipartRequest); } public byte[] getFileDataFromDrawable(Bitmap bitmap) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 80, byteArrayOutputStream); return byteArrayOutputStream.toByteArray(); } private void requestMultiplePermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); } }
Deeper Look In Main Activity
See the following lines
private Button btn; private ImageView imageView; private final int GALLERY = 1; private String upload_URL = "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php?"; private RequestQueue rQueue;
First is making an object of Button class.
Second is giving us the object of the ImageView class.
Third is creating a final integer variable GALLERY having the value as 1.
This final variable is not static, means that value of GALLERY is always 1, you can not change it.
Fourth line is making one string variable upload_URL which holds the URL to the web service.
Remember that at end of the web service, I have added a ? (question mark) sign. This sign is needed to add the parameter while making http call to this URL.
- Last line is simply making an object of the RequestQueue class.
- In onCreate() method, compiler will call the requestMultiplePermissions() method.
Following is the code block for requestMultiplePermissions() method.
private void requestMultiplePermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); }
- Above method uses the classes from Dexter library.
- This method will ask for runtime permissions (for READ and WRITE external storage).
Read the following coding lines
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } });
Compiler will execute the above lines when the user clicks on the button.
It will first create one intent. This intent is a Pick intent means that it will create a screen from where the user can pick the image.
When the user selects the image and clicks on OK button, compiler will run the onActivityResult() method.
Code for onActivityResult() method is as the following
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); // imageView.setImageBitmap(bitmap); uploadImage(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } }
First of all, compiler will check whether user have selected the image or not.
If user have not selected image then if(resultCode == this.RESULT.CANCELLED) condition will be true. So compiler will not do anything in this case.
When the user have selected one image then if(resultCode == GALLERY) condition will be true and compiler will first get URI of the image from the data.
From URI, it will get bitmap of the image.
Then it will call uploadImage() method with bitmap as the parameter of this method.
uploadImage()
Below is the coding lines for uploadImage() method
private void uploadImage(final Bitmap bitmap){ VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, upload_URL, new Response.Listener<NetworkResponse>() { @Override public void onResponse(NetworkResponse response) { Log.d("ressssssoo",new String(response.data)); rQueue.getCache().clear(); try { JSONObject jsonObject = new JSONObject(new String(response.data)); Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show(); jsonObject.toString().replace("\\\\",""); if (jsonObject.getString("status").equals("true")) { arraylist = new ArrayList<HashMap<String, String>>(); JSONArray dataArray = jsonObject.getJSONArray("data"); String url = ""; for (int i = 0; i < dataArray.length(); i++) { JSONObject dataobj = dataArray.getJSONObject(i); url = dataobj.optString("pathToFile"); } Picasso.get().load(url).into(imageView); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show(); } }) { /* * If you want to add more parameters with the image * you can do it here * here we have only one parameter with the image * which is tags * */ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> params = new HashMap<>(); // params.put("tags", "ccccc"); add string parameters return params; } /* *pass files using below method * */ @Override protected Map<String, DataPart> getByteData() { Map<String, DataPart> params = new HashMap<>(); long imagename = System.currentTimeMillis(); params.put("filename", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap))); return params; } }; volleyMultipartRequest.setRetryPolicy(new DefaultRetryPolicy( 0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); rQueue = Volley.newRequestQueue(MainActivity.this); rQueue.add(volleyMultipartRequest); }
First of all, compiler will create the object of the VolleyMultipartRequest class.
Using this object, we will make the http call.
There are two methods getParams() and getByteData() in this uploadImage() method.
getParams() is used to create string parameters. Means that key and value of the parameter in the string format only.
getByteData() will help us to send files to the server.
Here, key will be in string format but value will be in file format. We will pass our image using getByteData() method.
When the http call is successfull, compiler will run onResponse() method.
In this method, we will get the JSON response.
JSON response contains the URL of the uploaded image.
Using this URL, we will fetch this information with Picasso library and will preview it in Imageview.
4. Upload Image To Server In Android Using Multipart Retrofit2
Learn about Android Retrofit Multipart Upload Image to server (PHP – MySQL) example.
This tutorial will guide you to send multipart image retrofit from android device.
We will use multipartbody.part retrofit class to send image with multipart in this example.
When we upload image using retrofit 2 to remote server, we will get JSON response in string format.
After uploading the image, we will fetch it from the server also.
See the below video to demonstrate multipart retrofit.
PHP Scripts
Create a new file named uploadfile.php and add below code
<?php if($_SERVER['REQUEST_METHOD']=='POST'){ // echo $_SERVER["DOCUMENT_ROOT"]; // /home1/demonuts/public_html //including the database connection file include_once("config.php"); //$_FILES['image']['name'] give original name from parameter where 'image' == parametername eg. city.jpg //$_FILES['image']['tmp_name'] temporary system generated name $originalImgName= $_FILES['filename']['name']; $tempName= $_FILES['filename']['tmp_name']; $folder="uploadedFiles/"; $url = "https://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName; //update path as per your directory structure if(move_uploaded_file($tempName,$folder.$originalImgName)){ $query = "INSERT INTO upload_image_video (pathToFile) VALUES ('$url')"; if(mysqli_query($con,$query)){ $query= "SELECT * FROM upload_image_video WHERE pathToFile='$url'"; $result= mysqli_query($con, $query); $emparray = array(); if(mysqli_num_rows($result) > 0){ while ($row = mysqli_fetch_assoc($result)) { $emparray[] = $row; } echo json_encode(array( "status" => "true","message" => "Successfully file added!" , "data" => $emparray) ); }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } //echo "moved to ".$url; }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } } ?>
Another file is config.php Here is it’s source
<?php $host="localhost"; $user="your username"; $password="your password"; $db = "your db name"; $con = mysqli_connect($host,$user,$password,$db); // Check connection if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }else{ //echo "Connect"; } ?>
Step 1. Dependency and some permissions
First of all, make a new project in android studio.
Now in your build.gradle(Module :app) file, copy the below four lines.
implementation 'com.karumi:dexter:5.0.0' implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-scalars:2.5.0' implementation 'com.squareup.picasso:picasso:2.71828'
First line is integrating the dexter library in our project. This line will help us to ask the runtime permissions in easy manner.
Second line will enable us to use classes of the retrofit library.
Scalar library will give us right to convert the JSON response in to the string format.
Last line is about Picasso library. Using Picasso, we can fetch the image from the URL with just one line of code.
Now in your AndroidManifest.xml file, add the below three lines
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
These lines are adding permissions in our app. First line will give us INTERNET permission.
Second will allow us to read external storage while third one will help us to write external storage.
Step 2. Interface for Multipart
Now it is time to make an interface. Create a new class and give it a name like MultiInterface.java
Write down the following source code in MultiInterface.java
import okhttp3.MultipartBody; import okhttp3.RequestBody; import retrofit2.Call; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.Multipart; import retrofit2.http.POST; import retrofit2.http.Part; public interface MultiInterface { String IMAGEURL = "https://demonuts.com/Demonuts/JsonTest/Tennis/"; @Multipart @POST("uploadfile.php") Call<String> uploadImage( @Part MultipartBody.Part file, @Part("filename") RequestBody name ); }
First line is a string variable which holds the URL address of the web service.
@Multipart annotation is specifying to retrofit to use multipart.
@POST(“uploadfile.php”) is giving the file name of the web API.
uploadImage() method has two parameters. MultipartBody.Part will contain the image.
Step 3. Last Writings of code
In your activity_main.xml file, copy down the following code block
<?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="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:background="@color/colorAccent" android:textColor="#fff" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Select Image and upload to server" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Below image is uploaded to server Using Multipart Retrofit" android:layout_marginTop="5dp" android:textSize="23sp" android:gravity="center" android:textColor="#000"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" android:id="@+id/iv"/> </LinearLayout>
Three UI widgets are there in the above XML file.
First one is Button, second is text view and last is Image view.
When the user clicks the button, system will led you to selector screen.
Text view is saying the purpose of this example.
Image view will hold the uploaded image.
Now following code structure is made for MainActivity.java file.
import android.Manifest; import android.content.Intent; import android.graphics.Bitmap; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import com.karumi.dexter.Dexter; import com.karumi.dexter.MultiplePermissionsReport; import com.karumi.dexter.PermissionToken; import com.karumi.dexter.listener.DexterError; import com.karumi.dexter.listener.PermissionRequest; import com.karumi.dexter.listener.PermissionRequestErrorListener; import com.karumi.dexter.listener.multi.MultiplePermissionsListener; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import com.squareup.picasso.Picasso; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.scalars.ScalarsConverterFactory; public class MainActivity extends AppCompatActivity { private Button btn; private ImageView imageView; private final int GALLERY = 1; private static final String IMAGE_DIRECTORY = "/demonuts_upload_gallery"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestMultiplePermissions(); btn = findViewById(R.id.btn); imageView = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); // imageView.setImageBitmap(bitmap); String path = saveImage(bitmap); uploadImage(path); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } } private void uploadImage(String path){ String imgname = String.valueOf(Calendar.getInstance().getTimeInMillis()); Retrofit retrofit = new Retrofit.Builder() .baseUrl(MultiInterface.IMAGEURL) .addConverterFactory(ScalarsConverterFactory.create()) .build(); //Create a file object using file path File file = new File(path); // Parsing any Media type file RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file); MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("filename", file.getName(), requestBody); RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), imgname); MultiInterface getResponse = retrofit.create(MultiInterface.class); Call<String> call = getResponse.uploadImage(fileToUpload, filename); Log.d("assss","asss"); call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.d("mullllll", response.body().toString()); try { JSONObject jsonObject = new JSONObject(response.body().toString()); Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show(); jsonObject.toString().replace("\\\\",""); if (jsonObject.getString("status").equals("true")) { JSONArray dataArray = jsonObject.getJSONArray("data"); String url = ""; for (int i = 0; i < dataArray.length(); i++) { JSONObject dataobj = dataArray.getJSONObject(i); url = dataobj.optString("pathToFile"); } Picasso.get().load(url).into(imageView); } } catch (JSONException e) { e.printStackTrace(); } } @Override public void onFailure(Call call, Throwable t) { Log.d("gttt", call.toString()); } }); } private void requestMultiplePermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); } public String saveImage(Bitmap myBitmap) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); File wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY); // have the object build the directory structure, if needed. if (!wallpaperDirectory.exists()) { wallpaperDirectory.mkdirs(); } try { File f = new File(wallpaperDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); MediaScannerConnection.scanFile(this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null); fo.close(); Log.d("TAG", "File Saved::--->" + f.getAbsolutePath()); return f.getAbsolutePath(); } catch (IOException e1) { e1.printStackTrace(); } return ""; } }
Digging above code
Main activity holds the main logic of the example. So let us see it with some more information.
See the below lines
private Button btn; private ImageView imageView; private final int GALLERY = 1; private static final String IMAGE_DIRECTORY = "/demonuts_upload_gallery";
First two lines are making the objects of Button and ImageView classes respectively.
Third line is defining one integer constant.
Last line is a string constant which is a directory where we will save the image.
Now read the following code snippet
requestMultiplePermissions(); btn = findViewById(R.id.btn); imageView = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } });
Inside onCreate() method, compiler will first execute the requestMultiplePermissions() method.
requestMultiplePermissions() method has the below lines
private void requestMultiplePermissions(){ Dexter.withActivity(this) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new MultiplePermissionsListener() { @Override public void onPermissionsChecked(MultiplePermissionsReport report) { // check if all permissions are granted if (report.areAllPermissionsGranted()) { Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show(); } // check for permanent denial of any permission if (report.isAnyPermissionPermanentlyDenied()) { // show alert dialog navigating to Settings } } @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { token.continuePermissionRequest(); } }). withErrorListener(new PermissionRequestErrorListener() { @Override public void onError(DexterError error) { Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show(); } }) .onSameThread() .check(); }
This method is asking runtime permissions to the user. Typically, we need to ask for read and write external storage here.
After this method, compiler will again move to the onCreate() method.
Then it will set the button click logic. When the user clicks the button, it will create one intent. This intent will show images of the android device to the user.
User will have to select one image from here which will be uploaded to the server.
Compiler will call onActivityResult() method when the user selects the image.
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); // imageView.setImageBitmap(bitmap); String path = saveImage(bitmap); uploadImage(path); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } } } }
Here, compiler will fetch the Uri of the image. Then it will create a bitmap of the image from this Uri.
Compiler will use saveImage() method along with bitmap to save the image.
After saving the image, compiler will fetch it’s path and will pass this path to the uploadImage() method.
Following is the handy source code of uploadImage() method
private void uploadImage(String path){ String imgname = String.valueOf(Calendar.getInstance().getTimeInMillis()); Retrofit retrofit = new Retrofit.Builder() .baseUrl(MultiInterface.IMAGEURL) .addConverterFactory(ScalarsConverterFactory.create()) .build(); //Create a file object using file path File file = new File(path); // Parsing any Media type file RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file); MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("filename", file.getName(), requestBody); RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), imgname); MultiInterface getResponse = retrofit.create(MultiInterface.class); Call<String> call = getResponse.uploadImage(fileToUpload, filename); Log.d("assss","asss"); call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.d("mullllll", response.body().toString()); try { JSONObject jsonObject = new JSONObject(response.body().toString()); Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_SHORT).show(); jsonObject.toString().replace("\\\\",""); if (jsonObject.getString("status").equals("true")) { JSONArray dataArray = jsonObject.getJSONArray("data"); String url = ""; for (int i = 0; i < dataArray.length(); i++) { JSONObject dataobj = dataArray.getJSONObject(i); url = dataobj.optString("pathToFile"); } Picasso.get().load(url).into(imageView); } } catch (JSONException e) { e.printStackTrace(); } } @Override public void onFailure(Call call, Throwable t) { Log.d("gttt", call.toString()); } }); }
First line in above method is fetching current time in milliseconds. Compiler store it in string variable. We will use this value as a name of the image.
Then system will create the object of the Retrofit class. Here, .baseUrl(MultiInterface.IMAGEURL) will give the reference to the URL of the web service.
After this compiler will create file using path captured from the parameter.
Then an objects of RequestBody and Multipartbody.Part classes will be created.
Object of Call<Sring> is the call variable. getResponse.uploadImage() method will initiate the http request and call will use .enqueue() to finally fire call to the web service.
When the compiler get the JSON response from server, it will execute onResponse() method.
It will parse this JSON response in string format and will get the URL of the uploaded image using below line
url = dataobj.optString("pathToFile");
Finally, below code line will fetch the uploaded image from URL using Picasso library.
Picasso.get().load(url).into(imageView);
5. Android Upload Image From Gallery With httpurlconnection
Hello, all. Welcome to upload image from gallery in Android Studio example.
In upload image from gallery in Android tutorial, learn how to choose image from gallery and then send or upload it to PHP-MySQL server.
First, we will upload image to server then we will fetch this uploaded image into ImageView using AQuery Library.
First, check output of upload image from gallery in Android example, then we will develop it.
Developing PHP Script
Make a new PHP file named “config.php” and copy below
<?php $host="localhost"; $user="your username"; $password="your password"; $db = "your db name"; $con = mysqli_connect($host,$user,$password,$db); // Check connection if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }else{ //echo "Connect"; } ?>
Create a new PHP file and name it “uploadfile.php” and add below source code
<?php if($_SERVER['REQUEST_METHOD']=='POST'){ // echo $_SERVER["DOCUMENT_ROOT"]; // /home1/demonuts/public_html //including the database connection file include_once("config.php"); //$_FILES['image']['name'] give original name from parameter where 'image' == parametername eg. city.jpg //$_FILES['image']['tmp_name'] temporary system generated name $originalImgName= $_FILES['filename']['name']; $tempName= $_FILES['filename']['tmp_name']; $folder="uploadedFiles/"; $url = "http://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName; //update path as per your directory structure if(move_uploaded_file($tempName,$folder.$originalImgName)){ $query = "INSERT INTO upload_image_video (pathToFile) VALUES ('$url')"; if(mysqli_query($con,$query)){ $query= "SELECT * FROM upload_image_video WHERE pathToFile='$url'"; $result= mysqli_query($con, $query); $emparray = array(); if(mysqli_num_rows($result) > 0){ while ($row = mysqli_fetch_assoc($result)) { $emparray[] = $row; } echo json_encode(array( "status" => "true","message" => "Successfully file added!" , "data" => $emparray) ); }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } //echo "moved to ".$url; }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } } ?>
I have a folder named “uploadedFiles,” in which all uploaded images will be saved.
You need to change this line as per your folder directory
$url = "http://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName;
Step 1: Create a new project in Android Studio.
Step 2: Updating AndroidManifest.xml file
Add required permissions between <manifest>….</manifest> tag.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Final code for AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.exampledemo.parsaniahardik.uploadgalleryimage"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Step 3: Updating build.gradle(Project: project_name) file:
Add the following
maven { url 'https://jitpack.io' }
in the below structure.
allprojects { repositories { jcenter() } }
So final code for build.gradle(Project: project_name) will look like this:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() maven { url 'https://jitpack.io' } } } task clean(type: Delete) { delete rootProject.buildDir }
Step 4: Updating build.gradle(Module:app) file
Add following code into dependencies{}
compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1' compile('org.apache.httpcomponents:httpmime:4.3') { exclude module: "httpclient" } compile 'com.github.androidquery:androidquery:0.26.9'
Add below code
android{ useLibrary 'org.apache.http.legacy' } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' }
in the parent, android{} as below
android { compileSdkVersion 23 buildToolsVersion "23.0.3" ... }
Final source code for build.gradle(Module:app) will be:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.exampledemo.parsaniahardik.uploadgalleryimage" minSdkVersion 16 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } android{ useLibrary 'org.apache.http.legacy' } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1' compile('org.apache.httpcomponents:httpmime:4.3') { exclude module: "httpclient" } compile 'com.github.androidquery:androidquery:0.26.9' }
Step 5: Adding common classes
We will add some common classes which contain constant variables and public methods.
We can use these variables and methods anywhere in the whole project so that it will reduce data redundancy.
Means that we will write them only once and then we can use them anytime and anywhere when needed.
Names of the classes are:
- AndyUtils
- AsyncTaskCompleteListener (Interface)
- MultiPartRequester
- ParseContent
Step 6: Creating AndyUtils
Create a Java class named AndyUtils and add below source code
import android.app.ProgressDialog; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; public class AndyUtils { private static ProgressDialog mProgressDialog; public static void showSimpleProgressDialog(Context context, String title, String msg, boolean isCancelable) { try { if (mProgressDialog == null) { mProgressDialog = ProgressDialog.show(context, title, msg); mProgressDialog.setCancelable(isCancelable); } if (!mProgressDialog.isShowing()) { mProgressDialog.show(); } } catch (IllegalArgumentException ie) { ie.printStackTrace(); } catch (RuntimeException re) { re.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static void showSimpleProgressDialog(Context context) { showSimpleProgressDialog(context, null, "Loading...", false); } public static void removeSimpleProgressDialog() { try { if (mProgressDialog != null) { if (mProgressDialog.isShowing()) { mProgressDialog.dismiss(); mProgressDialog = null; } } } catch (IllegalArgumentException ie) { ie.printStackTrace(); } catch (RuntimeException re) { re.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static boolean isNetworkAvailable(Context context) { ConnectivityManager connectivity = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity == null) { return false; } else { NetworkInfo[] info = connectivity.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } } } return false; } }
This class contains a methods to show(showSimplrProgressDialog()) and remove(removeSimpleProgressDialog()) progress dialog when app is fetching JSON data from server.
AndyUtils also includes a method (isNetworkAvailable()) to check whether the Internet of Android device is on or off.
Step 7: Creating AsyncTaskCompleteListener Interface
Prepare new interface named AsyncTaskCompleteListener and add following source code
/** * Created by Parsania Hardik on 19/01/2016. */ public interface AsyncTaskCompleteListener { void onTaskCompleted(String response, int serviceCode); }
Step 8: Creating MultiPartRequester
Create a new Java class named “MultiPartRequester” and add below
import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MIME; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpConnectionParams; import org.apache.http.util.EntityUtils; import java.io.File; import java.util.Map; public class MultiPartRequester { private Map<String, String> map; private AsyncTaskCompleteListener mAsynclistener; private int serviceCode; private HttpClient httpclient; private Activity activity; private AsyncHttpRequest request; public MultiPartRequester(Activity activity, Map<String, String> map, int serviceCode, AsyncTaskCompleteListener asyncTaskCompleteListener) { this.map = map; this.serviceCode = serviceCode; this.activity = activity; // is Internet Connection Available... if (AndyUtils.isNetworkAvailable(activity)) { mAsynclistener = (AsyncTaskCompleteListener) asyncTaskCompleteListener; request = (AsyncHttpRequest) new AsyncHttpRequest().execute(map .get("url")); } else { showToast("Network is not available!!!"); } } class AsyncHttpRequest extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) { map.remove("url"); try { HttpPost httppost = new HttpPost(urls[0]); httpclient = new DefaultHttpClient(); HttpConnectionParams.setConnectionTimeout( httpclient.getParams(), 600000); MultipartEntityBuilder builder = MultipartEntityBuilder .create(); for (String key : map.keySet()) { if (key.equalsIgnoreCase("filename")) { File f = new File(map.get(key)); builder.addBinaryBody(key, f, ContentType.MULTIPART_FORM_DATA, f.getName()); } else { builder.addTextBody(key, map.get(key), ContentType .create("text/plain", MIME.DEFAULT_CHARSET)); } Log.d("TAG", key + "---->" + map.get(key)); // System.out.println(key + "---->" + map.get(key)); } httppost.setEntity(builder.build()); ActivityManager manager = (ActivityManager) activity .getSystemService(Context.ACTIVITY_SERVICE); if (manager.getMemoryClass() < 25) { System.gc(); } HttpResponse response = httpclient.execute(httppost); String responseBody = EntityUtils.toString( response.getEntity(), "UTF-8"); return responseBody; } catch (Exception e) { e.printStackTrace(); } catch (OutOfMemoryError oume) { System.gc(); Toast.makeText( activity.getParent().getParent(), "Run out of memory please colse the other background apps and try again!", Toast.LENGTH_LONG).show(); } finally { if (httpclient != null) httpclient.getConnectionManager().shutdown(); } return null; } @Override protected void onPostExecute(String response) { if (mAsynclistener != null) { mAsynclistener.onTaskCompleted(response, serviceCode); } } } private void showToast(String msg) { Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); } }
We will use methods of this class to establish a connection between an Android device and web server.
Step 9: Creating ParseContent
Open new Java class and give it a name ParseContent, then Add below source code
import android.app.Activity; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.HashMap; public class ParseContent { private final String KEY_SUCCESS = "status"; private final String KEY_MSG = "message"; private Activity activity; ArrayList<HashMap<String, String>> arraylist; public ParseContent(Activity activity) { this.activity = activity; } public boolean isSuccess(String response) { try { JSONObject jsonObject = new JSONObject(response); if (jsonObject.optString(KEY_SUCCESS).equals("true")) { return true; } else { return false; } } catch (JSONException e) { e.printStackTrace(); } return false; } public String getErrorCode(String response) { try { JSONObject jsonObject = new JSONObject(response); return jsonObject.getString(KEY_MSG); } catch (JSONException e) { e.printStackTrace(); } return "No data"; } public String getURL(String response) { String url=""; try { JSONObject jsonObject = new JSONObject(response); jsonObject.toString().replace("\\\\",""); if (jsonObject.getString(KEY_SUCCESS).equals("true")) { arraylist = new ArrayList<HashMap<String, String>>(); JSONArray dataArray = jsonObject.getJSONArray("data"); for (int i = 0; i < dataArray.length(); i++) { JSONObject dataobj = dataArray.getJSONObject(i); url = dataobj.optString("pathToFile"); } } } catch (JSONException e) { e.printStackTrace(); } return url; } }
In above source code, isSuccess(String response) method is used to check whether a status of response is true or false.
getErrorCode(String response) method is used to get the message of JSON data.
getURL(String response) method will parse JSON data.
Step 10: Updating activity_main.xml file
Copy and paste below source code in activity_main.xml file
<?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="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.exampledemo.parsaniahardik.uploadgalleryimage.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Select Image and upload to server" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Below image is fetched from server" android:layout_marginTop="5dp" android:textSize="23sp" android:gravity="center" android:textColor="#000"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" android:id="@+id/iv"/> </LinearLayout>
Step 11: Preparing MainActivity.java class
Add following source code in MainActivity.java class
import android.content.Intent; import android.graphics.Bitmap; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import com.androidquery.AQuery; import org.json.JSONException; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Calendar; import java.util.HashMap; public class MainActivity extends AppCompatActivity implements AsyncTaskCompleteListener { private ParseContent parseContent; private Button btn; private ImageView imageview; private static final String IMAGE_DIRECTORY = "/demonuts_upload_gallery"; private final int GALLERY = 1; private AQuery aQuery; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); parseContent = new ParseContent(this); aQuery = new AQuery(this); btn = (Button) findViewById(R.id.btn); imageview = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); String path = saveImage(bitmap); uploadImageToServer(path); //Toast.makeText(MainActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show(); //imageview.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } } } } private void uploadImageToServer(final String path) throws IOException, JSONException { if (!AndyUtils.isNetworkAvailable(MainActivity.this)) { Toast.makeText(MainActivity.this, "Internet is required!", Toast.LENGTH_SHORT).show(); return; } HashMap<String, String> map = new HashMap<String, String>(); map.put("url", "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php"); map.put("filename", path); new MultiPartRequester(this, map, GALLERY, this); AndyUtils.showSimpleProgressDialog(this); } @Override public void onTaskCompleted(String response, int serviceCode) { AndyUtils.removeSimpleProgressDialog(); Log.d("res", response.toString()); switch (serviceCode) { case GALLERY: if (parseContent.isSuccess(response)) { String url = parseContent.getURL(response); aQuery.id(imageview).image(url); } } } public String saveImage(Bitmap myBitmap) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); File wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY); // have the object build the directory structure, if needed. if (!wallpaperDirectory.exists()) { wallpaperDirectory.mkdirs(); } try { File f = new File(wallpaperDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); MediaScannerConnection.scanFile(this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null); fo.close(); Log.d("TAG", "File Saved::--->" + f.getAbsolutePath()); return f.getAbsolutePath(); } catch (IOException e1) { e1.printStackTrace(); } return ""; } }
Step 12: Description of MainActivity.java
MainActivity implements AsynTaskCompleteListener interface. So we will have to override onTaskCompleted() method.
public class MainActivity extends AppCompatActivity implements AsyncTaskCompleteListener
When the button is clicked, Gallery intent will be opened as following.
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, GALLERY); } });
When user selects image, compiler comes to onActivityResult() method as below.
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == GALLERY) { if (data != null) { Uri contentURI = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI); String path = saveImage(bitmap); uploadImageToServer(path); //Toast.makeText(MainActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show(); //imageview.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } } }
Here, image is saved and uploaded to server.
saveImage(bitmap) method will save the image as below.
public String saveImage(Bitmap myBitmap) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); File wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY); // have the object build the directory structure, if needed. if (!wallpaperDirectory.exists()) { wallpaperDirectory.mkdirs(); } try { File f = new File(wallpaperDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); MediaScannerConnection.scanFile(this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null); fo.close(); Log.d("TAG", "File Saved::--->" + f.getAbsolutePath()); return f.getAbsolutePath(); } catch (IOException e1) { e1.printStackTrace(); } return ""; }
In above code, IMAGE_DIRECTORY is the folder name, in which images will be saved.
uploadImageToServer() method will call Web Service.
private void uploadImageToServer(final String path) throws IOException, JSONException { if (!AndyUtils.isNetworkAvailable(MainActivity.this)) { Toast.makeText(MainActivity.this, "Internet is required!", Toast.LENGTH_SHORT).show(); return; } HashMap<String, String> map = new HashMap<String, String>(); map.put("url", "http://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php"); map.put("filename", path); new MultiPartRequester(this, map, GALLERY, this); AndyUtils.showSimpleProgressDialog(this); }
From here, compiler will go to onTaskCompleted() method.
@Override public void onTaskCompleted(String response, int serviceCode) { AndyUtils.removeSimpleProgressDialog(); Log.d("res", response.toString()); switch (serviceCode) { case GALLERY: if (parseContent.isSuccess(response)) { String url = parseContent.getURL(response); aQuery.id(imageview).image(url); } } }
The following line will fetch image from URL.
aQuery.id(imageview).image(url);
So enough for upload image from gallery in android with httpsurlconnection example.
6. Android Upload Image From Camera To PHP-MySQL Server
Hello, Geeks. You are at upload image from camera in Android Studio example.
In upload image from camera in Android tutorial, learn how to choose image from camera and then send or upload it to PHP-MySQL server.
First, check output of upload image from camera in Android example, then we will develop it.
Developing PHP Script
Make a new PHP file named “config.php” and copy below
<?php $host="localhost"; $user="your username"; $password="your password"; $db = "your db name"; $con = mysqli_connect($host,$user,$password,$db); // Check connection if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }else{ //echo "Connect"; } ?>
Create a new PHP file and name it “uploadfile.php” and add below source code
<?php if($_SERVER['REQUEST_METHOD']=='POST'){ // echo $_SERVER["DOCUMENT_ROOT"]; // /home1/demonuts/public_html //including the database connection file include_once("config.php"); //$_FILES['image']['name'] give original name from parameter where 'image' == parametername eg. city.jpg //$_FILES['image']['tmp_name'] temporary system generated name $originalImgName= $_FILES['filename']['name']; $tempName= $_FILES['filename']['tmp_name']; $folder="uploadedFiles/"; $url = "http://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName; if(move_uploaded_file($tempName,$folder.$originalImgName)){ $query = "INSERT INTO upload_image_video (pathToFile) VALUES ('$url')"; if(mysqli_query($con,$query)){ $query= "SELECT * FROM upload_image_video WHERE pathToFile='$url'"; $result= mysqli_query($con, $query); $emparray = array(); if(mysqli_num_rows($result) > 0){ while ($row = mysqli_fetch_assoc($result)) { $emparray[] = $row; } echo json_encode(array( "status" => "true","message" => "Successfully file added!" , "data" => $emparray) ); }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } //echo "moved to ".$url; }else{ echo json_encode(array( "status" => "false","message" => "Failed!") ); } } ?>
I have a folder “uploadedFiles,” in which all uploaded images will be saved.
Change this line as per your folder directory
$url = "http://www.demonuts.com/Demonuts/JsonTest/Tennis/uploadedFiles/".$originalImgName;
Step 2: Updating AndroidManifest.xml file
Add required permissions between <manifest>….</manifest> tag.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Final code for AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.exampledemo.parsaniahardik.uploadimagecamera"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Step 3: Updating build.gradle(Project: project_name) file:
Add the following
maven { url 'https://jitpack.io' }
in the below structure.
allprojects { repositories { jcenter() } }
So final code for build.gradle(Project: project_name) will look like this:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() maven { url 'https://jitpack.io' } } } task clean(type: Delete) { delete rootProject.buildDir }
Step 4: Updating build.gradle(Module:app) file
Add following code into dependencies{}
compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1' compile('org.apache.httpcomponents:httpmime:4.3') { exclude module: "httpclient" } compile 'com.github.androidquery:androidquery:0.26.9'
Add below code
android{ useLibrary 'org.apache.http.legacy' } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' }
in the parent, android{} as below
android { compileSdkVersion 23 buildToolsVersion "23.0.3" ... }
Final source code for build.gradle(Module:app) will be:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.exampledemo.parsaniahardik.uploadimagecamera" minSdkVersion 16 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } android{ useLibrary 'org.apache.http.legacy' } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1' compile('org.apache.httpcomponents:httpmime:4.3') { exclude module: "httpclient" } compile 'com.github.androidquery:androidquery:0.26.9' }
Step 5: Adding common classes
We will add some common classes which contain constant variables and public methods.
We can use these variables and methods anywhere in the whole project so that it will reduce data redundancy.
Means that we will write them only once and then we can use them anytime and anywhere when needed.
Names of the classes are:
- AndyUtils
- AsyncTaskCompleteListener (Interface)
- MultiPartRequester
- ParseContent
Step 6: Creating AndyUtils
Create a Java class named AndyUtils and add below source code
import android.app.ProgressDialog; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; public class AndyUtils { private static ProgressDialog mProgressDialog; public static void showSimpleProgressDialog(Context context, String title, String msg, boolean isCancelable) { try { if (mProgressDialog == null) { mProgressDialog = ProgressDialog.show(context, title, msg); mProgressDialog.setCancelable(isCancelable); } if (!mProgressDialog.isShowing()) { mProgressDialog.show(); } } catch (IllegalArgumentException ie) { ie.printStackTrace(); } catch (RuntimeException re) { re.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static void showSimpleProgressDialog(Context context) { showSimpleProgressDialog(context, null, "Loading...", false); } public static void removeSimpleProgressDialog() { try { if (mProgressDialog != null) { if (mProgressDialog.isShowing()) { mProgressDialog.dismiss(); mProgressDialog = null; } } } catch (IllegalArgumentException ie) { ie.printStackTrace(); } catch (RuntimeException re) { re.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static boolean isNetworkAvailable(Context context) { ConnectivityManager connectivity = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity == null) { return false; } else { NetworkInfo[] info = connectivity.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } } } return false; } }
This class contains a methods to show(showSimplrProgressDialog()) and remove(removeSimpleProgressDialog()) progress dialog when app is fetching JSON data from server.
AndyUtils also includes a method (isNetworkAvailable()) to check whether the Internet of Android device is on or off.
Step 7: Creating AsyncTaskCompleteListener Interface
Prepare new interface named AsyncTaskCompleteListener and add following source code
/** * Created by Parsania Hardik on 19/01/2016. */ public interface AsyncTaskCompleteListener { void onTaskCompleted(String response, int serviceCode); }
Step 8: Creating MultiPartRequester
Create a new Java class named “MultiPartRequester” and add below
import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MIME; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpConnectionParams; import org.apache.http.util.EntityUtils; import java.io.File; import java.util.Map; public class MultiPartRequester { private Map<String, String> map; private AsyncTaskCompleteListener mAsynclistener; private int serviceCode; private HttpClient httpclient; private Activity activity; private AsyncHttpRequest request; public MultiPartRequester(Activity activity, Map<String, String> map, int serviceCode, AsyncTaskCompleteListener asyncTaskCompleteListener) { this.map = map; this.serviceCode = serviceCode; this.activity = activity; // is Internet Connection Available... if (AndyUtils.isNetworkAvailable(activity)) { mAsynclistener = (AsyncTaskCompleteListener) asyncTaskCompleteListener; request = (AsyncHttpRequest) new AsyncHttpRequest().execute(map .get("url")); } else { showToast("Network is not available!!!"); } } class AsyncHttpRequest extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) { map.remove("url"); try { HttpPost httppost = new HttpPost(urls[0]); httpclient = new DefaultHttpClient(); HttpConnectionParams.setConnectionTimeout( httpclient.getParams(), 600000); MultipartEntityBuilder builder = MultipartEntityBuilder .create(); for (String key : map.keySet()) { if (key.equalsIgnoreCase("filename")) { File f = new File(map.get(key)); builder.addBinaryBody(key, f, ContentType.MULTIPART_FORM_DATA, f.getName()); } else { builder.addTextBody(key, map.get(key), ContentType .create("text/plain", MIME.DEFAULT_CHARSET)); } Log.d("TAG", key + "---->" + map.get(key)); // System.out.println(key + "---->" + map.get(key)); } httppost.setEntity(builder.build()); ActivityManager manager = (ActivityManager) activity .getSystemService(Context.ACTIVITY_SERVICE); if (manager.getMemoryClass() < 25) { System.gc(); } HttpResponse response = httpclient.execute(httppost); String responseBody = EntityUtils.toString( response.getEntity(), "UTF-8"); return responseBody; } catch (Exception e) { e.printStackTrace(); } catch (OutOfMemoryError oume) { System.gc(); Toast.makeText( activity.getParent().getParent(), "Run out of memory please colse the other background apps and try again!", Toast.LENGTH_LONG).show(); } finally { if (httpclient != null) httpclient.getConnectionManager().shutdown(); } return null; } @Override protected void onPostExecute(String response) { if (mAsynclistener != null) { mAsynclistener.onTaskCompleted(response, serviceCode); } } } private void showToast(String msg) { Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); } }
We will use methods of this class to establish a connection between an Android device and web server.
Step 9: Creating ParseContent
Open new Java class and give it a name ParseContent, then Add below source code
import android.app.Activity; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.HashMap; public class ParseContent { private final String KEY_SUCCESS = "status"; private final String KEY_MSG = "message"; private Activity activity; ArrayList<HashMap<String, String>> arraylist; public ParseContent(Activity activity) { this.activity = activity; } public boolean isSuccess(String response) { try { JSONObject jsonObject = new JSONObject(response); if (jsonObject.optString(KEY_SUCCESS).equals("true")) { return true; } else { return false; } } catch (JSONException e) { e.printStackTrace(); } return false; } public String getErrorCode(String response) { try { JSONObject jsonObject = new JSONObject(response); return jsonObject.getString(KEY_MSG); } catch (JSONException e) { e.printStackTrace(); } return "No data"; } public String getURL(String response) { String url=""; try { JSONObject jsonObject = new JSONObject(response); jsonObject.toString().replace("\\\\",""); if (jsonObject.getString(KEY_SUCCESS).equals("true")) { arraylist = new ArrayList<HashMap<String, String>>(); JSONArray dataArray = jsonObject.getJSONArray("data"); for (int i = 0; i < dataArray.length(); i++) { JSONObject dataobj = dataArray.getJSONObject(i); url = dataobj.optString("pathToFile"); } } } catch (JSONException e) { e.printStackTrace(); } return url; } }
In above source code, isSuccess(String response) method is used to check whether a status of response is true or false.
getErrorCode(String response) method is used to get the message of JSON data.
getURL(String response) method will parse JSON data.
Step 10: Updating activity_main.xml file
Copy and paste below source code in activity_main.xml file
<?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="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.exampledemo.parsaniahardik.uploadgalleryimage.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:layout_gravity="center_horizontal" android:layout_marginTop="20dp" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Capture Image and upload to server" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Below image is fetched from server" android:layout_marginTop="5dp" android:textSize="23sp" android:gravity="center" android:textColor="#000"/> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" android:id="@+id/iv"/> </LinearLayout>
Step 11: Preparing MainActivity.java class
Add following source code in MainActivity.java class
import android.content.Intent; import android.graphics.Bitmap; import android.media.MediaScannerConnection; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import com.androidquery.AQuery; import org.json.JSONException; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Calendar; import java.util.HashMap; public class MainActivity extends AppCompatActivity implements AsyncTaskCompleteListener{ private ParseContent parseContent; private Button btn; private ImageView imageview; private static final String IMAGE_DIRECTORY = "/demonuts_upload_camera"; private final int CAMERA = 1; private AQuery aQuery; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); parseContent = new ParseContent(this); aQuery = new AQuery(this); btn = (Button) findViewById(R.id.btn); imageview = (ImageView) findViewById(R.id.iv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, CAMERA); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == CAMERA) { Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); String path = saveImage(thumbnail); try { uploadImageToServer(path); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } } private void uploadImageToServer(final String path) throws IOException, JSONException { if (!AndyUtils.isNetworkAvailable(MainActivity.this)) { Toast.makeText(MainActivity.this, "Internet is required!", Toast.LENGTH_SHORT).show(); return; } HashMap<String, String> map = new HashMap<String, String>(); map.put("url", "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php"); map.put("filename", path); new MultiPartRequester(this, map, CAMERA, this); AndyUtils.showSimpleProgressDialog(this); } @Override public void onTaskCompleted(String response, int serviceCode) { AndyUtils.removeSimpleProgressDialog(); Log.d("res", response.toString()); switch (serviceCode) { case CAMERA: if (parseContent.isSuccess(response)) { String url = parseContent.getURL(response); aQuery.id(imageview).image(url); } } } public String saveImage(Bitmap myBitmap) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); File wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY); // have the object build the directory structure, if needed. if (!wallpaperDirectory.exists()) { wallpaperDirectory.mkdirs(); } try { File f = new File(wallpaperDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); MediaScannerConnection.scanFile(this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null); fo.close(); Log.d("TAG", "File Saved::--->" + f.getAbsolutePath()); return f.getAbsolutePath(); } catch (IOException e1) { e1.printStackTrace(); } return ""; } }
Step 12: Description of MainActivity.java
MainActivity implements AsynTaskCompleteListener interface. So we will have to override onTaskCompleted() method.
public class MainActivity extends AppCompatActivity implements AsyncTaskCompleteListener
When the button is clicked, Camera intent will be opened as following.
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, CAMERA);
When user captures the image, compiler comes to onActivityResult() method as below.
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == this.RESULT_CANCELED) { return; } if (requestCode == CAMERA) { Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); String path = saveImage(thumbnail); try { uploadImageToServer(path); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } }
Here, image is saved and uploaded to server.
saveImage(bitmap) method will save the image as below.
public String saveImage(Bitmap myBitmap) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); File wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY); // have the object build the directory structure, if needed. if (!wallpaperDirectory.exists()) { wallpaperDirectory.mkdirs(); } try { File f = new File(wallpaperDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); MediaScannerConnection.scanFile(this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null); fo.close(); Log.d("TAG", "File Saved::--->" + f.getAbsolutePath()); return f.getAbsolutePath(); } catch (IOException e1) { e1.printStackTrace(); } return ""; }
In above code, IMAGE_DIRECTORY is the folder name, in which images will be saved.
uploadImageToServer() method will call Web Service.
private void uploadImageToServer(final String path) throws IOException, JSONException { if (!AndyUtils.isNetworkAvailable(MainActivity.this)) { Toast.makeText(MainActivity.this, "Internet is required!", Toast.LENGTH_SHORT).show(); return; } HashMap<String, String> map = new HashMap<String, String>(); map.put("url", "http://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php"); map.put("filename", path); new MultiPartRequester(this, map, CAMERA, this); AndyUtils.showSimpleProgressDialog(this); }
From here, compiler will go to onTaskCompleted() method.
@Override public void onTaskCompleted(String response, int serviceCode) { AndyUtils.removeSimpleProgressDialog(); Log.d("res", response.toString()); switch (serviceCode) { case CAMERA: if (parseContent.isSuccess(response)) { String url = parseContent.getURL(response); aQuery.id(imageview).image(url); } } }
The following line will fetch image from URL.
aQuery.id(imageview).image(url);
So enough for upload image from camera in android example.