Membuat Aplikasi Android Upload Gambar
Langkah awal dalam tutorial yaitu membuat database dengan nama volley_upload dengan nama tabel volley_upload dan struktur tabelnya seperti berikut :
Column name | Data Type | lenght | Primary Key | Not Null | Auto Increment |
---|---|---|---|---|---|
id | int | 10 | v | v | v |
name | varchar | 50 | |||
photo | text |
Membuat web service untuk parsing data aplikasi android.
koneksi.php
Sebagai koneksi aplikasi ke database. Coding-nya dibawah.
<?php $server = "localhost"; $username = "root"; $password = "enter"; $database = "volley_upload"; $con = mysqli_connect($server, $username, $password, $database); if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } ?>
upload.php
Untuk upload gambar ke sever dan menyimpan data di database. Coding-nya dibawah.
<?php include_once "koneksi.php"; class emp{} $image = $_POST['image']; $name = $_POST['name']; if (empty($name)) { $response = new emp(); $response->success = 0; $response->message = "Please dont empty Name."; die(json_encode($response)); } else { $random = random_word(20); $path = "images/".$random.".png"; // sesuiakan ip address laptop/pc atau URL server $actualpath = "http://192.168.10.177/android/upload_image/$path"; $query = mysqli_query($con, "INSERT INTO volley_upload (photo,name) VALUES ('$actualpath','$name')"); if ($query){ file_put_contents($path,base64_decode($image)); $response = new emp(); $response->success = 1; $response->message = "Successfully Uploaded"; die(json_encode($response)); } else{ $response = new emp(); $response->success = 0; $response->message = "Error Upload image"; die(json_encode($response)); } } // fungsi random string pada gambar untuk menghindari nama file yang sama function random_word($id = 20){ $pool = '1234567890abcdefghijkmnpqrstuvwxyz'; $word = ''; for ($i = 0; $i < $id; $i++){ $word .= substr($pool, mt_rand(0, strlen($pool) -1), 1); } return $word; } mysqli_close($con); ?>
Buat project baru di Android Studio File ⇒ New Project. Kemudian pilih Blank Activity dan melanjutkannya hingga selesai.
activity_main.xml
Layout container untuk floating action button.
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.chandra.uploadimage.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> <android.support.design.widget.FloatingActionButton android:id="@+id/buttonUpload" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_menu_upload" /> </android.support.design.widget.CoordinatorLayout>
content_main.xml
Untuk menampilkan gambar setelah memilih dari galeri.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.chandra.uploadimage.MainActivity" tools:showIn="@layout/activity_main"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Choose Image" android:id="@+id/buttonChoose" android:drawableRight="@android:drawable/ic_menu_gallery"/> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/imageView" /> <EditText android:id="@+id/editText" android:hint="Enter a Name" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
Buka build.gradle dan tambahkan volley library didalamnya.
compile 'com.android.volley:volley:1.0.0'
build.gradle
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support:design:26.+' compile 'com.android.volley:volley:1.0.0' }
Agar project terstruktur dan terorganisir, buat 2 paket dengan nama app dan volley. Untuk membuat paket baru , klik kanan pada src=>New=>Peckage dan memberikan nama paket. Contoh : com.chandra.uploadimage.
Buat class dengan nama LruBitmapCache.java didalam package volley dan tambah coding seperti dibawah ini. Class ini berfungsi untuk mengatur caching network image dalam penyimpanan.
LruBitmapCache.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com. import android.graphics.Bitmap; import android.support.v4.util.LruCache; import com.android.volley.toolbox.ImageLoader.ImageCache; public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageCache { public static int getDefaultLruCacheSize() { final int maxMemory = ( int ) (Runtime.getRuntime().maxMemory() / 1024 ); final int cacheSize = maxMemory / 8 ; return cacheSize; } public LruBitmapCache() { this (getDefaultLruCacheSize()); } public LruBitmapCache( int sizeInKiloBytes) { super (sizeInKiloBytes); } @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024 ; } @Override public Bitmap getBitmap(String url) { return get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { put(url, bitmap); } } |
Buat class AppController.java didalam package app dan tambah coding seperti dibawah ini. Class tunggal yang menginisialisasi class global yang diperlukan. Semua objek yang berhubungan dengan volley diinisialisasi di sini.
AppController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
package com. import android.app.Application; import android.text.TextUtils; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.Volley; import com. public class AppController extends Application { public static final String TAG = AppController. class .getSimpleName(); private RequestQueue mRequestQueue; private ImageLoader mImageLoader; LruBitmapCache mLruBitmapCache; private static AppController mInstance; @Override public void onCreate() { super .onCreate(); mInstance = this ; } public static synchronized AppController getInstance() { return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null ) { mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } return mRequestQueue; } public ImageLoader getImageLoader() { getRequestQueue(); if (mImageLoader == null ) { getLruBitmapCache(); mImageLoader = new ImageLoader( this .mRequestQueue, mLruBitmapCache); } return this .mImageLoader; } public LruBitmapCache getLruBitmapCache() { if (mLruBitmapCache == null ) mLruBitmapCache = new LruBitmapCache(); return this .mLruBitmapCache; } public <T> void addToRequestQueue(Request<T> req, String tag) { req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } public <T> void addToRequestQueue(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancelPendingRequests(Object tag) { if (mRequestQueue != null ) { mRequestQueue.cancelAll(tag); } } } |
Buka class MainActivity.java dan tambahkan coding seperti dibawah ini. Class ini berfungsi untuk meng-upload gambar dan nama ke server.
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
package com. import android.app.ProgressDialog; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.provider.MediaStore; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.StringRequest; import com. import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity { Button buttonChoose; FloatingActionButton buttonUpload; Toolbar toolbar; ImageView imageView; EditText txt_name; Bitmap bitmap, decoded; int success; int PICK_IMAGE_REQUEST = 1 ; int bitmap_size = 60 ; // range 1 - 100 private static final String TAG = MainActivity. class .getSimpleName(); /* 10.0.2.2 adalah IP Address localhost Emulator Android Studio. Ganti IP Address tersebut dengan IP Address Laptop jika di RUN di HP/Genymotion. HP/Genymotion dan Laptop harus 1 jaringan! */ private String UPLOAD_URL = " http://10.0.2.2/android/upload_image/upload.php" ; private static final String TAG_SUCCESS = "success" ; private static final String TAG_MESSAGE = "message" ; private String KEY_IMAGE = "image" ; private String KEY_NAME = "name" ; String tag_json_obj = "json_obj_req" ; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); buttonChoose = (Button) findViewById(R.id.buttonChoose); buttonUpload = (FloatingActionButton) findViewById(R.id.buttonUpload); txt_name = (EditText) findViewById(R.id.editText); imageView = (ImageView) findViewById(R.id.imageView); buttonChoose.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { showFileChooser(); } }); buttonUpload.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { uploadImage(); } }); } public String getStringImage(Bitmap bmp) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, bitmap_size, baos); byte [] imageBytes = baos.toByteArray(); String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT); return encodedImage; } private void uploadImage() { //menampilkan progress dialog final ProgressDialog loading = ProgressDialog.show( this , "Uploading..." , "Please wait..." , false , false ); StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.e(TAG, "Response: " + response.toString()); try { JSONObject jObj = new JSONObject(response); success = jObj.getInt(TAG_SUCCESS); if (success == 1 ) { Log.e( "v Add" , jObj.toString()); Toast.makeText(MainActivity. this , jObj.getString(TAG_MESSAGE), Toast.LENGTH_LONG).show(); kosong(); } else { Toast.makeText(MainActivity. this , jObj.getString(TAG_MESSAGE), Toast.LENGTH_LONG).show(); } } catch (JSONException e) { e.printStackTrace(); } //menghilangkan progress dialog loading.dismiss(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //menghilangkan progress dialog loading.dismiss(); //menampilkan toast Toast.makeText(MainActivity. this , error.getMessage().toString(), Toast.LENGTH_LONG).show(); Log.e(TAG, error.getMessage().toString()); } }) { @Override protected Map<String, String> getParams() { //membuat parameters Map<String, String> params = new HashMap<String, String>(); //menambah parameter yang di kirim ke web servis params.put(KEY_IMAGE, getStringImage(decoded)); params.put(KEY_NAME, txt_name.getText().toString().trim()); //kembali ke parameters Log.e(TAG, "" + params); return params; } }; AppController.getInstance().addToRequestQueue(stringRequest, tag_json_obj); } 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); } @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 ) { Uri filePath = data.getData(); try { //mengambil fambar dari Gallery bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath); // 512 adalah resolusi tertinggi setelah image di resize, bisa di ganti. setToImageView(getResizedBitmap(bitmap, 512 )); } catch (IOException e) { e.printStackTrace(); } } } private void kosong() { imageView.setImageResource( 0 ); txt_name.setText( null ); } private void setToImageView(Bitmap bmp) { //compress image ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, bitmap_size, bytes); decoded = BitmapFactory.decodeStream( new ByteArrayInputStream(bytes.toByteArray())); //menampilkan gambar yang dipilih dari camera/gallery ke ImageView imageView.setImageBitmap(decoded); } // fungsi resize image public Bitmap getResizedBitmap(Bitmap image, int maxSize) { int width = image.getWidth(); int height = image.getHeight(); float bitmapRatio = ( float ) width / ( float ) height; if (bitmapRatio > 1 ) { width = maxSize; height = ( int ) (width / bitmapRatio); } else { height = maxSize; width = ( int ) (height * bitmapRatio); } return Bitmap.createScaledBitmap(image, width, height, true ); } } |
Tambahkan perijinan INTERNET dan android:name=”.app.AppController” dalam tag application pada AndroidManifest.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = " http://schemas.android.com/apk/res/android" package = "com.chandra.uploadimage" > < uses-permission android:name = "android.permission.INTERNET" /> <!-- tambahan --> < application android:name = ".app.AppController" <!-- tambahan --> android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> < activity android:name = ".MainActivity" android:label = "@string/app_name" android:theme = "@style/AppTheme.NoActionBar" > < intent-filter > < action android:name = "android.intent.action.MAIN" /> < category android:name = "android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > </ application > </ manifest > |
Terakhir, mari kita Run Aplikasinya.