web analytics

Android Code : เลือกรูปใน gallery ด้วย Multipicker library และอัพโหลดไปยัง server

cover-2

ผมมมีโอกาสได้ทำแอปเกี่ยวกับเลือกรูปแล้วอัพโหลดอยู่หลายครั้ง บทความนี้ จึงมาบันทึก และแชร์สั้นๆเกี่ยวกับการเลือกรูปใน Gallery แล้วอัพโหลดไปยัง server เผื่อจะเป็นประโยชน์

 

เลือกรูปภาพใน gallery ด้วย Multipicker Library

การเลือกรูปจากใน Gallery บนเครื่อง จริงๆแล้วก็สามารถเขียนเอง แบบใช้ Intent ก็ได้เช่นกัน แต่ว่ามันออกจะลำบาก แล้วบางทีก็ใช้งานจริงไม่ค่อยได้ ผมเลยเลือกใช้ไลบรารี่ดีกว่า โดยตัวที่ใช้คือ Android Multipicker Library ใช้ง่าย สะดวกดี

 

เพิ่ม Dependency

compile 'com.kbeanie:multipicker:1.1.1@aar'

หรือ ดูวิธีการใช้งาน รายละเอียดทั้งหมดที่
https://github.com/coomar2841/android-multipicker-library

 

ประกาศตัวแปร ImagePicker สำหรับเตรียมเปิด gallery ขึ้นมา

ImagePicker imagePicker;
imagePicker = new ImagePicker(MainActivity.this);

 

หากต้องการกำหนดให้เลือกได้หลายภาพ

imagePicker.allowMultiple();

 

กำหนด Callback ว่า เลือกรูปแล้วให้ทำอะไร ที่ onImagesChosen

imagePicker.setImagePickerCallback(new ImagePickerCallback() {
                                               @Override
                                               public void onImagesChosen(List<ChosenImage> list) {
                                                   // Do somethig
                                               }

                                               @Override
                                               public void onError(String message) {
                                                   // Do error handling
                                               }
                                           }
);

 

เปิด gallery ขึ้นมา

imagePicker.pickImage();

3

 

 

แต่ว่า Callback จะถูกเรียกจริงๆ เราต้องทำการ submit  ก่อน ที่ onActivityResult

ดังนั้นพอเราเลือกรูปแล้ว onActivityResult จะถูกเรียก
เราก็เช็ค resustCode แล้ว submit ทีนี้ Callback ก็จะถูกเรียกทันที

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == Picker.PICK_IMAGE_DEVICE) {
                imagePicker.submit(data);
            }
        }
    }

 

แสดงรูปใน ImageView เมื่อเลือกรูป

ที่ callback จะเห็นว่า ChosenImage เป็น List หากเรากำหนดให้เลือกหลายรูป ใน list ก็จะมีหลายตัวนั่นเอง

imagePicker.setImagePickerCallback(new ImagePickerCallback() {
                                               @Override
                                               public void onImagesChosen(List<ChosenImage> list) {
                                                   // get path and create file.
                                                   String path = list.get(0).getOriginalPath();
                                                   File file = new File(path);
      
                                                   // convert file to bitmap and set to imageView.
                                                   if(file.exists()){
                                                        Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
                                                        imgView.setImageBitmap(myBitmap);
                                                    }
                                               }

                                               @Override
                                               public void onError(String message) {
                                                   // Do error handling
                                               }
                                           }
);

 

อัพโหลดภาพขึ้น server ด้วย Retrofit 2.1

หลังจากเลือกรูปแล้ว ทีนี้เราก็สามารถนำรูปไปใช้ทำอะไรก็แล้วแต่สะดวก เดี๋ยวเราจะมาลองเขียนอัพโหลดภาพกัน
ไม่ได้ลงรายละเอียดเกี่ยวกับ Retrofit นะครับ และไม่ได้ลงรายละเอียดในฝั่ง server ด้วย

 

การติดต่อกับ server จะใช้ไลบรารี่ Retrofit 2.1 , okHttp เป็นตัวช่วยติดต่อสื่อสาร
server จะตอบกลับมาเป็น JSON จึงใช้ Gson เป็นไลบรารี่แปลงมาเป็น Java class

 

dependencies

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.3.1'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

 

กำหนด Callback หลังจากเลือกรูป โดยการส่งค่าต่างๆ  หากมีการแนบไฟล์จะ เรียกว่า Multi part การส่งค่าไปยัง server จะต้องใช้ RequestBody

imagePicker.setImagePickerCallback(new ImagePickerCallback() {
                                               @Override
                                               public void onImagesChosen(List<ChosenImage> list) {

                                                   String path = list.get(0).getOriginalPath();
                                                   File file = new File(path);

                                                   RequestBody user_id = RequestBody.create(MediaType.parse("text/plain"), "1"));
                                                   RequestBody img = RequestBody.create(MediaType.parse("image/jpeg"), file);

                                                   callServerUploadImageProfile(img, user_id);
                                               }

                                               @Override
                                               public void onError(String message) {
                                                   // Do error handling
                                               }
                                           }
);

 

Method สำหรับอัพโหลดรูป

 private void callServerUploadImageProfile(RequestBody img, RequestBody user_id) {

        Call call = MyService.getService().updateImageProfile(img, user_id);
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                if (response.isSuccessful()) {
                    //MessageUploadImageDAO message = (MessageUploadImageDAO) response.body();
                    Toast.makeText(MainActivity.this,"Uploaded", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                // handle error.
            }
        });
}

 

สมมุติว่าจะอัพโหลดไปที่ URL : http://benzneststudios.com/api/v1/edit/user/picture
แบบ method POST

 

จะเห็นว่าต้องมี 2 คลาสที่จำเป็น คือ

MyService.java
baseUrl คือ url หลักของ API เรา

public class MyService {
    public static MyAPI getService() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://benzneststudios.com/api/v1/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        return retrofit.create(MyAPI.class);
    }
}

 

MyAPI.java
สำหรับกำหนด method ไว้ส่งค่าไปยัง server เช่น updateImageProfile()

ให้เป็น method POST และ MultiPart (แนบไฟล์)

public interface MyAPI {
    @Multipart
    @POST("edit/user/picture")
    Call<MessageUploadImageDAO> updateImageProfile(@Part("picture\"; filename=\"image.jpg\" ") RequestBody picture,
                                                   @Part("user_id") RequestBody user_id);
}

MessageUploadImageDAO คือ คลาส data ที่เกิดจากการแปลง JSON ที่ตอบกลับจาก server มาเป็น Java object ดังนั้น เราก็ต้องรู้ก่อนว่า พอเราส่งรูปไปที่ server แล้ว จากนั้น server จะส่ง JSON กลับมาเป็นอย่างไร

 

ตัวอย่าง JSON ที่ตอบกลับมา
พอส่งรูปแล้ว server จะส่ง url รูปกลับมาให้

{
  "success": true,
  "url" : "https://benzneststudios.com/blog/wp-content/uploads/2016/08/cover-2-300x175.png"
}

 

เราจึงเขียนคลาส MessageUploadImageDAO ที่ตรงกับ JSON ที่ตอบกลับมาได้ดังนี้

MessageUploadImageDAO.java

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class MessageUploadImageDAO {

   @SerializedName("success")
   @Expose
   private Boolean success;

   @SerializedName("url")
   @Expose
   private String url;

      public Boolean getSuccess() {
          return success;
      }

      public void setSuccess(Boolean success) {
          this.success = success;
      }

      public String getUrl() {
          return url;
      }

      public void setUrl(String url) {
          this.url = url;
      }
}

 

การแปลง JSON เป็น Java Class

ถ้า JSON ซับซ้อนมากๆ เราก็ต้องเขียนกันมือหงิกเลยสิ แต่ไม่ต้องห่วง เพราะมีตัวช่วยแปลง JSON มาเป็น Java class

เช่น http://www.jsonschema2pojo.org/

 

แค่แปะ JSON ลงไป แล้วเลือก Source type = JSON และ Annotation style = Gson1

 

จากนั้นลองกดปุ่ม Preview ดู จะได้ Java class เรียบร้อย ไม่ต้องนั่งพิมเอง สบายตัวไปเลย หรือจะ export เป็นไฟล์เลยก็ได้

2

 

ตอนนี้ก็สามารถส่งไฟล์ภาพไปยัง server ได้แล้ว

 

สรุป

การเลือกรูปจาก Gallery สามารถใช้ไลบรารี่ multi-picker สะดวก และง่ายด้วย ไม่ได้เลือกได้แค่รูปนะ ยังถ่ายภาพ หรือเลือกวิดีโอได้ด้วย ส่วนการอัพโหลดภาพก็ใช้ไลบรารี่ Retrofit ในการส่งข้อมูลแบบ Multipart การส่งข้อมูลตอบกลับจาก server ก็มักจะส่งข้อมูลแบบ JSON กลับมา ซึ่งเราก็แค่สร้าง Java class ขึ้นมาเพื่อรองรับรูปแบบ JSON นั่นเอง นำไปประยุกต์ใช้ได้

หวังว่า บทความจะเป็นประโยชน์ครับ
(: