Hi các bạn trước khi bắt đầu bài viết các bạn chưa xem các bài viết trước có thể quay lại xem để hiểu hơn:
Trước khi băt đầu bài viết để hiểu hơn về retrofit các bạn xem trước các bài viết này:
Tìm Hiểu về Retrofit
Ở bài viết này mình sẽ hướng dẫn các bạn cách upload một image lên server sử dụng thư viện retrofit 2 theo cách mà mình hay làm.
Lưu ý đây không phải cách dựa trên document của Retrofit 2
Cấu trúc project:
Các thư viên hỗ trợ:
compile 'com.squareup.retrofit2:retrofit:2.0.2' compile 'com.squareup.retrofit2:converter-gson:2.0.2' compile 'com.jakewharton:butterknife:8.4.0' apt 'com.jakewharton:butterknife-compiler:8.4.0' compile 'com.github.bumptech.glide:glide:3.7.0'
- Tạo bảng
CREATE TABLE `imageupload`( `id` INT PRIMARY KEY AUTO_INCREMENT, `url` VARCHAR(50) NOT NULL, UNIQUE (id) );
2. Viết trang PHP như sau
<?php require_once('dbConnect.php'); mysqli_set_charset($con,'utf8'); $response = array(); if($_SERVER['REQUEST_METHOD']=='POST') { $imageName = $_POST['imageName']; $imageCode = $_POST['imageCode']; // Tạo một thư mục chứa ảnh // imaName là tên ảnh, để không trùng các bạn có thể add thêm ngày tháng cho nó $path = "upload/$imageName"; // Đường dẫn $actualpath = "http://dev.androidcoban.com/blog/$path"; $query = "INSERT INTO imageupload(url)VALUES ('$actualpath')"; if(mysqli_query($con,$query)){ // đẩy data vào path file_put_contents($path,base64_decode($imageCode)); $response["message"] = "Success"; } mysqli_close($con); } else{ $response["message"] = "Failed"; } // echoing JSON response echo json_encode($response); ?>
3. Tạo giao diện
<?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="match_parent" android:layout_height="wrap_content" android:text="Choose Image" android:id="@+id/buttonChoose" tools:ignore="HardcodedText" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/imageView" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Upload Image" android:id="@+id/buttonUpload" /> </LinearLayout>
4. Bắt đầu code
- Viết API
public interface APIUpload { @FormUrlEncoded @POST("upload-image.php") Call<Message> uploadImage(@Field("imageCode")String imgCode, @Field("imageName")String imgName); }
- Viết model nhận thông tin trả về
public class Message implements Serializable{ @SerializedName("message") private String message; //contructor //getter/ setter }
- MainActivity
Viết hàm checkpermistion cho android 6.0
//Check permistion android 6.0 private void checkPermistion() { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) { } else { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1); } } }
- Lấy ảnh trong thư viện sử dụng Intent
@OnClick(R.id.buttonChoose) public void chooseImage(){ checkPermistion(); Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, 0); }
- Nhận data, load ảnh lên imageView
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 0 && resultCode == MainActivity.this.RESULT_OK) { PATH = RealPathUtil.getPath(MainActivity.this, data.getData()); Uri uri = Uri.fromFile(new File(PATH)); // Get name imgName = PATH.substring(PATH.lastIndexOf("/")+1); Toast.makeText(MainActivity.this, imgName, Toast.LENGTH_LONG).show(); try { //Get BitMap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); } catch (IOException e) { e.printStackTrace(); } // Load image Glide.with(MainActivity.this).load(uri).override(420, 594).centerCrop().into(imageView); Toast.makeText(this, PATH, Toast.LENGTH_LONG).show(); } }
- Encode bitmap toString để upload lên server
// Encode bitmap to String public String getBitMap(Bitmap bmp){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 50, baos); byte[] imageBytes = baos.toByteArray(); String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT); return encodedImage; }
- Hàm upload như sau
@OnClick(R.id.buttonUpload) public void uploadImage() { imgCode = getBitMap(bitmap); Retrofit retrofit = new Retrofit.Builder() .baseUrl(UPLOAD_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); APIUpload apiUpload = retrofit.create(APIUpload.class); Call<Message> call = apiUpload.uploadImage(imgCode,imgName); call.enqueue(new Callback<Message>() { @Override public void onResponse(Call<Message> call, Response<Message> response) { Message message = response.body(); if (message.getMessage().equals("Success")) { Toast.makeText(MainActivity.this, "Upload Success!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "Upload Failed!", Toast.LENGTH_SHORT).show(); } } @Override public void onFailure(Call<Message> call, Throwable t) { Log.e(TAG, t.getMessage()); } }); }
- Lớp Util xử dụng để get path của hình ảnh ()
public class RealPathUtil { /// get path API >19 KITKAT public static String getPath(final Context context, final Uri uri) { // DocumentProvider if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context The context. * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } }
Kết quả:
Check link tại đây: http://dev.androidcoban.com/blog/upload/
Vậy là xong tiến hành chạy và kiểm tra kết quả! Chúc các bạn thành công!
Bình luận đã bị khoá.