Android Image Upload Using Retrofit and Ion(Observer Pattern)Part-1

Youbaraj POUDEL
AndroidPub
Published in
4 min readMar 27, 2017

--

Using Ion

  1. What is ion?
  2. Ion is an android library for asynchronous networking and image loading(Displaying bitmaps,Image Uploading, Downloading).There are many other libraries for image manipulation which we will discuss later.

Ion is light weight and very easy to implement for beginners. Today i am going to teach you how to use Ion for Image Upload in MySql Server using android. Let’s start.

Server Configuration:

  1. Install Xampp or Wamp server.
  2. Create a folder androidImageUpload inside htdocs(For xampp) or www(For wamp).

3.Create imageupload.php file and write code as below.

<?php
echo $_FILES['image']['name'] . '<br/>';
ini_set('upload_max_filesize', '10M');
$target_path = "uploads/";
$target_path = $target_path . basename($_FILES['image']['name']);

try {
if (!move_uploaded_file($_FILES['image']['tmp_name'], $target_path)) {
throw new Exception('Could not move file');
}

echo "Image uploaded";
} catch (Exception $e) {
die('Image did not upload: ' . $e->getMessage());
}
?>

4.Create another folder uploads in which you want to save image.

We just have completed server configuration.Now I am going to show you android client part.

Steps1: Create android project and add ion dependency on build.gradle of module.

compile 'com.koushikdutta.ion:ion:2.+'

Step 2:Add permission for internet, camera and external storage respectivally.

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

Step 3:Create Server Configuration class which holds static variables required for Network call.

ServerConfig.java

Note: 192.168.0.109 is computers IP which will be different in your case.

public class ServerConfig {
public static final String IMAGE_UPLOAD_URL = "http://192.168.0.109/androidImageUpload/imageupload.php";
public static final String IMAGE_DIRECTORY_NAME = "imageuploadtest";
}

Step 4:Create an activity from which you want to upload image to server.

i.Check wheater or not device support camera.

if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"device doesn't support camera",
Toast.LENGTH_LONG).show();
finish();
}

ii.check device has camera hardware or not.

private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}

iii.Capture image from camera .

private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent,1001);
}

iv.Create a function that require image file path as an argument and do image upload logic here.

void uploadImage(String mImagePath) {
if (!NetworkUtil.getConnectivityStatusString(this)) {
Toast.makeText(this, "no internet", Toast.LENGTH_SHORT).show();
return;
}
final File fileToUpload = new File(mImagePath);
Ion.with(ChangeProfilePictureActivity.this)
.load("POST",ServerConfig.IMAGE_UPLOAD_URL)
.uploadProgressHandler(new ProgressCallback() {
@Override
public void
onProgress(long uploaded, long total) {
}
})
.setMultipartFile("image", "image/jpeg", fileToUpload)
.asString()
.setCallback(new FutureCallback<String>() {
@Override
public void
onCompleted(Exception e, String result) {
dismisDialog();
if (result != null) {
//Upload Success
} else {
//Upload Failed
}
}
});
}

Finally your MainActivity class look like this:

MainActivity.java

public class MainActivity extends Activity {
private Uri fileUri;
private Button btnCapturePicture;

@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCapturePicture = (Button) findViewById(R.id.btn_take_image);
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
@Override
public void
onClick(View v) {
captureImage();
}
});


// Check wheater or not device support camera
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"device doesn't support camera",
Toast.LENGTH_LONG).show();
finish();
}
}

/**
* check device has camera hardware or not
* */
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}


private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent,1001);
}


@Override
protected void
onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("file_uri", fileUri);
}

@Override
protected void
onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
fileUri = savedInstanceState.getParcelable("file_uri");
}

@Override
protected void
onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001) {
if (resultCode == RESULT_OK) {
uploadImage(fileUri.getPath());

} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();

} else {
Toast.makeText(getApplicationContext(),
"Error capturing image", Toast.LENGTH_SHORT)
.show();
}

}
}

void uploadImage(String mImagePath) {
if (!NetworkUtil.getConnectivityStatusString(this)) {
Toast.makeText(this, "no internet", Toast.LENGTH_SHORT).show();
return;
}

final File fileToUpload = new File(mImagePath);
Ion.with(ChangeProfilePictureActivity.this)
.load("POST", ServerConfig.IP + ServerConfig.BASE_URL + ServerConfig.IMAGE_UPLOAD)
.uploadProgressHandler(new ProgressCallback() {
@Override
public void
onProgress(long uploaded, long total) {
}
})
.setMultipartFile("image", "image/jpeg", fileToUpload)
.setMultipartParameter("email", preference.getEmail())
.asString()
.setCallback(new FutureCallback<String>() {
@Override
public void
onCompleted(Exception e, String result) {
dismisDialog();
if (result != null) {
//Upload Success
} else {
//Upload Failed
}

}
});
}



public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type) {

File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
ServerConfig.IMAGE_DIRECTORY_NAME);

if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "Oops! Failed create "
+ ServerConfig.IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
}else {
return null;
}

return mediaFile;
}
}

Its almost done.Run the sample and upload image.

Image has been uploaded.

Thanks for visiting my post.We will be working with retrofit and Observer pattern in my next tutorial(Part-2).

If you have any queries or if you like my post please like, share or comment.

--

--

Youbaraj POUDEL
AndroidPub

Android Software Engineer (Contributor), Writer