Halo gaes, pada postingan kali ini saya ingin berbagi pengalaman membuat upload service android untuk upload gambar ke server.
Tutorial kali ini adalah bagaimana cara saya menyimpan file gambar dari lokal phone ke direktori sekaligus menyimpan URL gambar ke database.
Prosesnya, saya menggunakan Android Upload Service Library untuk memudahkan pengerjaan. Sebagai langkah awal, mari kita buat dulu server side code.
1. Buat Server Side Codes untuk Android Upload Image
Hal pertama yang perlu kita bangun adalah server side web services, dalam kasus ini saya menggunakan PHP, MySQL, dan wamp server. Sekarang, ayo ikuti aku cara menghandle upload file.
Buat database di phpmyadmin

Buat folder untuk aplikasi webservice kita di root directory (../wamp/www) Pada kasus ini saya beri nama foldernya "AndroidUploadImage".
Buat folder lagi di dalam folder "AndroidUploadImage" untuk menampung semua file gambar yang terupload, pada kasus ini saya beri nama "uploads".
Lanjut, buat file "dbDetails.php" dan taruh di folder "AndroidUploadImage". Isi file tersebut dengan kode di bawah ini.
<?php
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('DB','db_images');
Lanjut, buat file lagi bernama "upload.php" dan isi dengan kode berikut.
<?php
//importing dbDetails file
require_once 'dbDetails.php';
//this is our upload folder
$upload_path = 'uploads/';
//Getting the server ip
$server_ip = gethostbyname(gethostname());
//creating the upload url
$upload_url = 'http://'.$server_ip.'/AndroidImageUpload/'.$upload_path;
//response array
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){
//checking the required parameters from the request
if(isset($_POST['name']) and isset($_FILES['image']['name'])){
//connecting to the database
$con = mysqli_connect(HOST,USER,PASS,DB) or die('Unable to Connect...');
//getting name from the request
$name = $_POST['name'];
//getting file info from the request
$fileinfo = pathinfo($_FILES['image']['name']);
//getting the file extension
$extension = $fileinfo['extension'];
//file url to store in the database
$file_url = $upload_url . getFileName() . '.' . $extension;
//file path to upload in the server
$file_path = $upload_path . getFileName() . '.'. $extension;
//trying to save the file in the directory
try{
//saving the file
move_uploaded_file($_FILES['image']['tmp_name'],$file_path);
$sql = "INSERT INTO `db_images`.`images` (`id`, `url`, `name`) VALUES (NULL, '$file_url', '$name');";
//adding the path and name to database
if(mysqli_query($con,$sql)){
//filling response array with values
$response['error'] = false;
$response['url'] = $file_url;
$response['name'] = $name;
}
//if some error occurred
}catch(Exception $e){
$response['error']=true;
$response['message']=$e->getMessage();
}
//displaying the response
echo json_encode($response);
//closing the connection
mysqli_close($con);
}else{
$response['error']=true;
$response['message']='Please choose a file';
}
}
/*
We are generating the file name
so this method will return a file name for the image to be upload
*/
function getFileName(){
$con = mysqli_connect(HOST,USER,PASS,DB) or die('Unable to Connect...');
$sql = "SELECT max(id) as id FROM images";
$result = mysqli_fetch_array(mysqli_query($con,$sql));
mysqli_close($con);
if($result['id']==null)
return 1;
else
return ++$result['id'];
}
Sekarang, test kodenya menggunakan aplikasi POSTMAN. Aplikasi ini sangat familiar di kalangan programmer RestFull webservice, biasa digunakan untuk menguji API mereka.

Jika pengujian yang kamu lakukan menghasilkan respon seperti gambar di atas, maka selamat! kode kamu bekerja dengan baik. Sekarang kamu dapat cek database dan direktori "uploads" yang telah kamu buat tadi.

Oke, serverside beres! sekarang mari kita lanjutkan dengan membuat project Android di Android Studio.
2. Membuat Project Android Studio
Baru saja kita menuntaskan pekerjaan di sisi server, jangan lengah dulu karena kita masih ada satu pekerjaan lagi yaitu programming sisi klien, dalam kasus ini adalah mobile android.
Buat project baru android studio, terserah kamu mau kasih nama apa, nanti tinggal sesuaikan saja nama packagenya dengan apa yang telah kamu buat.
Buat class baru bernama "Constants.java" isi dengan kode berikut. **kode ini berisi string path lokasi file php di server side, penting untuk diperhatikan dan disesuaikan dengan milik kamu jika perlu*
package com.bundet.androidimageupload;
/**
* Created by Belal on 6/10/2016.
*/
public class Constants {
public static final String UPLOAD_URL = "http://192.168.94.1/AndroidImageUpload/upload.php";
public static final String IMAGES_URL = "http://192.168.94.1/AndroidImageUpload/getImages.php";
}
Ubah IP address, sesuaikan dengan IP addess system yang sedang kamu gunakan. Bagaimana cara mengetahuinya? kamu bisa menggunakan CMD dan ketik "IPCONFIG", atau bisa juga cek detail network di Tray menu Windows kamu.
Lanjut, kita perlu buat android upload service di project Android Studio.
3. Membuat Android Upload Service
Buka build.gradle (level app) dan tambahkan dependencies berikut.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
//Add this line
compile 'net.gotev:uploadservice:2.1'
}
Lanjut ke file activity_main.xml dan tambahkan kode berikut.
<?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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.simplifiedcoding.androidimageupload.MainActivity">
<LinearLayout
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/buttonChoose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Select" />
<EditText
android:id="@+id/editTextName"
android:hint="Name For Image"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/buttonUpload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Upload" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Kode diatas akan menghasilkan tampilan ini.

Perhatikan preview diatas, kita punya tombol untuk select gambar dan untuk upload gambar, sedangkan editText untuk fleksibilitas renaming file gambar.
Lanjut, mari kita ke file MainActivity.java dan tambahkan kode berikut.
package com.bundet.androidimageupload;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import net.gotev.uploadservice.MultipartUploadRequest;
import net.gotev.uploadservice.UploadNotificationConfig;
import java.io.IOException;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//Declaring views
private Button buttonChoose;
private Button buttonUpload;
private ImageView imageView;
private EditText editText;
//Image request code
private int PICK_IMAGE_REQUEST = 1;
//storage permission code
private static final int STORAGE_PERMISSION_CODE = 123;
//Bitmap to get image from gallery
private Bitmap bitmap;
//Uri to store the image uri
private Uri filePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Requesting storage permission
requestStoragePermission();
//Initializing views
buttonChoose = (Button) findViewById(R.id.buttonChoose);
buttonUpload = (Button) findViewById(R.id.buttonUpload);
imageView = (ImageView) findViewById(R.id.imageView);
editText = (EditText) findViewById(R.id.editTextName);
//Setting clicklistener
buttonChoose.setOnClickListener(this);
buttonUpload.setOnClickListener(this);
}
/*
* This is the method responsible for image upload
* We need the full image path and the name for the image in this method
* */
public void uploadMultipart() {
//getting name for the image
String name = editText.getText().toString().trim();
//getting the actual path of the image
String path = getPath(filePath);
//Uploading code
try {
String uploadId = UUID.randomUUID().toString();
//Creating a multi part request
new MultipartUploadRequest(this, uploadId, Constants.UPLOAD_URL)
.addFileToUpload(path, "image") //Adding file
.addParameter("name", name) //Adding text parameter to the request
.setNotificationConfig(new UploadNotificationConfig())
.setMaxRetries(2)
.startUpload(); //Starting the upload
} catch (Exception exc) {
Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show();
}
}
//method to show file chooser
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
//handling the image chooser activity result
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//method to get the file path from uri
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
//Requesting permission
private void requestStoragePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
return;
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
//If the user has denied the permission previously your code will come to this block
//Here you can explain why you need this permission
//Explain here why you need this permission
}
//And finally ask for the permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
//This method will be called when the user will tap on allow or deny
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onClick(View v) {
if (v == buttonChoose) {
showFileChooser();
}
if (v == buttonUpload) {
uploadMultipart();
}
}
}
Terakhir, mari kita finishing di file Manifest.xml, atur permission untuk akses internet dan storage.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.simplifiedcoding.androidimageupload">
<!-- add these permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_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>
Run -> build dan lihat hasilnya.

Yeaaah! good job!
4. Fetching Gambar Terupload
Agar dapat mengintip gambar apa saja yang sudah terupload di serverside, maka kita perlu buat API bernama "fetching". Bagaimana caranya? tambahkan saja file bernama "getImages.php" dan isi dengan kode berikut.
<?php
//Importing dbdetails file
require_once 'dbDetails.php';
//connection to database
$con = mysqli_connect(HOST,USER,PASS,DB) or die('Unable to Connect...');
//sql query to fetch all images
$sql = "SELECT * FROM images";
//getting images
$result = mysqli_query($con,$sql);
//response array
$response = array();
$response['error'] = false;
$response['images'] = array();
//traversing through all the rows
while($row = mysqli_fetch_array($result)){
$temp = array();
$temp['id']=$row['id'];
$temp['name']=$row['name'];
$temp['url']=$row['url'];
array_push($response['images'],$temp);
}
//displaying the response
echo json_encode($response);
Kode diatas akan menghasilkan output JSON, sebagimana contoh cuplikan berikut.
{
"error":false,
"images":[
{
"id":"1",
"name":"Belal Khan",
"url":"http:\/\/192.168.94.1\/AndroidImageUpload\/uploads\/1.jpg"
},
{
"id":"2",
"name":"Belal",
"url":"http:\/\/192.168.94.1\/AndroidImageUpload\/uploads\/2.jpg"
},
{
"id":"3",
"name":"",
"url":"http:\/\/192.168.94.1\/AndroidImageUpload\/uploads\/3.jpg"
},
{
"id":"4",
"name":"Belal Khan",
"url":"http:\/\/192.168.94.1\/AndroidImageUpload\/uploads\/4.jpg"
}
]
}
Episode berikutnya kita akan belajar bagaimana menambilkan gambar menggunakan output JSON diatas.