เครื่องมือเลือกรูปภาพ

กล่องโต้ตอบเครื่องมือเลือกรูปภาพจะปรากฏขึ้นพร้อมกับไฟล์สื่อในอุปกรณ์ เลือกรูปภาพที่จะแชร์กับแอป
รูปที่ 1 เครื่องมือเลือกรูปภาพมี UI ที่ใช้งานง่ายสำหรับการแชร์รูปภาพกับแอปของคุณ

เครื่องมือเลือกรูปภาพมีอินเทอร์เฟซที่เรียกดูได้ซึ่งแสดงคลังสื่อของผู้ใช้ โดยจัดเรียงตามวันที่จากใหม่สุดไปเก่าสุด ดังที่แสดงใน Codelab แนวทางปฏิบัติแนะนำด้านความเป็นส่วนตัว เครื่องมือเลือกรูปภาพเป็นวิธีที่ปลอดภัยและมีอยู่แล้วในตัวสำหรับให้ผู้ใช้มอบสิทธิ์ให้แอปของคุณเข้าถึงได้เฉพาะรูปภาพและวิดีโอที่เลือกไว้เท่านั้น แทนที่จะเข้าถึงคลังสื่อทั้งหมด

ผู้ใช้ที่มีผู้ให้บริการสื่อในระบบคลาวด์ที่มีสิทธิ์ในอุปกรณ์จะเลือกรูปภาพและวิดีโอที่จัดเก็บไว้จากระยะไกลได้ด้วย ดูข้อมูลเพิ่มเติมเกี่ยวกับผู้ให้บริการสื่อระบบคลาวด์

เครื่องมือจะอัปเดตโดยอัตโนมัติเพื่อมอบฟังก์ชันเพิ่มเติมให้แก่ผู้ใช้แอปเมื่อเวลาผ่านไปโดยไม่ต้องเปลี่ยนแปลงโค้ดเลย

ใช้สัญญา Jetpack Activity

เพื่อให้การผสานรวมเครื่องมือเลือกรูปภาพทำได้ง่ายขึ้น ให้รวมไลบรารี androidx.activity เวอร์ชัน 1.7.0 ขึ้นไป

ใช้สัญญาผลลัพธ์กิจกรรมต่อไปนี้เพื่อเปิดเครื่องมือเลือกรูปภาพ

หากเครื่องมือเลือกรูปภาพไม่พร้อมใช้งานในอุปกรณ์ ไลบรารีจะเรียกใช้การดำเนินการตาม Intent ACTION_OPEN_DOCUMENT โดยอัตโนมัติแทน Intent นี้ใช้ได้ในอุปกรณ์ที่ใช้ Android 4.4 (ระดับ API 19) ขึ้นไป คุณสามารถตรวจสอบว่าเครื่องมือเลือกรูปภาพพร้อมใช้งานในอุปกรณ์ที่ระบุหรือไม่โดยเรียกใช้ isPhotoPickerAvailable()

เลือกรายการสื่อ 1 รายการ

หากต้องการเลือกรายการสื่อรายการเดียว ให้ใช้สัญญาผลลัพธ์กิจกรรม PickVisualMedia ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

ยอดดู

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

ยอดดู

// Registers a photo picker activity launcher in single-select mode.
ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
        registerForActivityResult(new PickVisualMedia(), uri -> {
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: " + uri);
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.VideoOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
String mimeType = "image/gif";
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(new PickVisualMedia.SingleMimeType(mimeType))
        .build());

เขียน

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = rememberLauncherForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

เลือกรายการสื่อหลายรายการ

หากต้องการเลือกรายการสื่อหลายรายการ ให้กำหนดจำนวนไฟล์สื่อสูงสุดที่เลือกได้ ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

ยอดดู

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

ยอดดู

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia =
        registerForActivityResult(new PickMultipleVisualMedia(5), uris -> {
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (!uris.isEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: " + uris.size());
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

เขียน

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        rememberLauncherForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

แพลตฟอร์มจะจำกัดจำนวนไฟล์สูงสุดที่คุณสามารถขอให้ผู้ใช้เลือกในเครื่องมือเลือกรูปภาพ หากต้องการเข้าถึงขีดจำกัดนี้ ให้เรียกใช้ getPickImagesMaxLimit() ในอุปกรณ์ที่ไม่รองรับเครื่องมือเลือกรูปภาพ ระบบจะไม่สนใจขีดจำกัดนี้

อุปกรณ์ที่พร้อมใช้งาน

เครื่องมือเลือกรูปภาพพร้อมใช้งานในอุปกรณ์ที่มีคุณสมบัติตรงตามเกณฑ์ต่อไปนี้

อุปกรณ์รุ่นเก่าที่ใช้ Android 4.4 (ระดับ API 19) ถึง Android 10 (ระดับ API 29) และอุปกรณ์ Android Go ที่ใช้ Android 11 หรือ 12 ซึ่งรองรับบริการ Google Play สามารถติดตั้งเครื่องมือเลือกรูปภาพเวอร์ชันที่พอร์ตไปยังเวอร์ชันเก่าได้ หากต้องการเปิดใช้การติดตั้งโมดูลเครื่องมือเลือกรูปภาพที่พอร์ตไปยังเวอร์ชันเก่าโดยอัตโนมัติผ่านบริการ Google Play ให้เพิ่มรายการต่อไปนี้ลงในแท็ก <application> ในไฟล์ Manifest ของแอป

<!-- Trigger Google Play services to install the backported photo picker module. -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies"
         android:enabled="false"
         android:exported="false"
         tools:ignore="MissingClass">
    <intent-filter>
        <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
    </intent-filter>
    <meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>

คงสิทธิ์เข้าถึงไฟล์สื่อไว้

โดยค่าเริ่มต้น ระบบจะให้สิทธิ์แอปเข้าถึงไฟล์สื่อจนกว่าอุปกรณ์จะรีสตาร์ทหรือจนกว่าแอปจะหยุดทำงาน หากแอปของคุณทำงานที่ใช้เวลานาน เช่น การอัปโหลดไฟล์ขนาดใหญ่ในเบื้องหลัง คุณอาจต้องคงสิทธิ์เข้าถึงนี้ไว้เป็นระยะเวลานานขึ้น โดยเรียกใช้เมธอด takePersistableUriPermission() ดังนี้

Kotlin

val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flag)

Java

int flag = Intent.FLAG_GRANT_READ_URI_PERMISSION;
context.contentResolver.takePersistableUriPermission(uri, flag);

จัดการวิดีโอ HDR ด้วยการแปลง

Android 13 (API 33) เปิดตัวความสามารถในการจับภาพวิดีโอ High Dynamic Range (HDR) แม้ว่า HDR จะมอบประสบการณ์การรับชมที่สมบูรณ์ยิ่งขึ้น แต่แอปเก่าบางแอปอาจไม่พร้อมที่จะจัดการกับรูปแบบใหม่เหล่านี้ ซึ่งทำให้เกิดปัญหาต่างๆ เช่น การแสดงสีที่ไม่เป็นธรรมชาติระหว่างการเล่น (เช่น ใบหน้าที่มีสีเขียว) เพื่อแก้ไขช่องว่างด้านความเข้ากันได้นี้ เครื่องมือเลือกรูปภาพจึงมีฟีเจอร์การแปลงที่สามารถแปลงวิดีโอ HDR เป็นรูปแบบ Standard Dynamic Range (SDR) โดยอัตโนมัติก่อนที่จะส่งให้แอปที่ขอ

เป้าหมายหลักของการแปลงรหัสเครื่องมือเลือกรูปภาพคือการมอบประสบการณ์การใช้งานสื่อที่สอดคล้องและแม่นยำในแอปพลิเคชันที่หลากหลายมากขึ้น แม้แต่แอปพลิเคชันที่ยังไม่รองรับ HDR อย่างชัดเจน เครื่องมือเลือกรูปภาพมีเป้าหมายเพื่อปรับปรุงความเข้ากันได้ของแอปและมอบประสบการณ์ของผู้ใช้ที่ราบรื่นด้วยการแปลงวิดีโอ HDR เป็น SDR

วิธีการทำงานของการแปลงไฟล์ในเครื่องมือเลือกรูปภาพ

การแปลง HDR ของเครื่องมือเลือกรูปภาพไม่ได้เปิดใช้โดยค่าเริ่มต้น หากต้องการเปิดใช้ฟีเจอร์นี้ แอปของคุณต้องประกาศความสามารถในการจัดการรูปแบบสื่ออย่างชัดเจนเมื่อเปิดเครื่องมือเลือกรูปภาพ

แอปของคุณจะให้ความสามารถในการประมวลผลสื่อแก่เครื่องมือเลือกรูปภาพ ซึ่งทำได้เมื่อเปิดเครื่องมือเลือกรูปภาพโดยใช้ไลบรารี AndroidX Activity โดยเพิ่ม mediaCapabilities ลงใน PickVisualMediaRequest.Builder เราได้เพิ่ม API ใหม่ setMediaCapabilitiesForTranscoding(capabilities: MediaCapabilities?) ลงใน PickVisualMediaRequest.Builder เพื่ออำนวยความสะดวกในเรื่องนี้

คุณควบคุมลักษณะการทำงานของการแปลง HDR ได้โดยใช้คลาส MediaCapabilities ระบุออบเจ็กต์ MediaCapabilities ที่ระบุประเภท HDR ที่แอปรองรับอย่างเจาะจง (เช่น TYPE_HLG10, TYPE_HDR10, TYPE_HDR10_PLUS, TYPE_DOLBY_VISION)

หากต้องการปิดใช้การแปลงทั้งหมด ให้ส่ง null สำหรับ MediaCapabilities ระบบจะถือว่าประเภท HDR ใดๆ ที่ไม่ได้ระบุไว้อย่างชัดเจนในความสามารถที่คุณระบุไว้ไม่ได้รับการรองรับ API นี้รองรับใน Android 13 (ระดับ API 33) ขึ้นไป และมีคำอธิบายประกอบเป็น @RequiresApi(Build.VERSION_CODES.TIRAMISU)

import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
import androidx.annotation.RequiresApi
import android.os.Build
import android.util.Log
import android.provider.MediaStore

// Registers a photo picker activity launcher.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
    // Callback invoked after media selected or picker activity closed.
    if (uri != null) {
        Log.d("photo picker", "Selected URI: $uri")
    } else {
        Log.d("photo picker", "No media selected")
    }
}

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun launchPhotoPickerWithTranscodingSupport() {
    val mediaCapabilities = MediaCapabilities.Builder()
        .addSupportedHdrType(MediaCapabilities.HdrType.TYPE_HLG10)
        .build()

    // Launch the photo picker and let the user choose only videos with
    // transcoding enabled.
    pickMedia.launch(PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.VideoOnly)
        .setMediaCapabilitiesForTranscoding(mediaCapabilities)
        .build())
}

การแปลงโดยเครื่องมือเลือกรูปภาพจะอิงตามทั้งความสามารถด้านสื่อของแอปและวิดีโอที่เลือก ระบบจะแสดงผล URI ของวิดีโอที่แปลงแล้วหากมีการแปลง

ข้อควรพิจารณาที่สำคัญสำหรับการแปลงไฟล์ HDR

  • ประสิทธิภาพและพื้นที่เก็บข้อมูล: การแปลงใช้เวลาในการประมวลผลและสร้างไฟล์ใหม่ ซึ่งจะใช้พื้นที่เก็บข้อมูล
  • ขีดจำกัดความยาววิดีโอ: เพื่อสร้างสมดุลระหว่างประสบการณ์ของผู้ใช้กับข้อจำกัดด้านพื้นที่เก็บข้อมูล เราจึงจำกัดความยาววิดีโอไว้ที่ 1 นาที
  • การจัดการไฟล์ที่แคชไว้: ระบบจะล้างไฟล์ที่แปลงแล้วซึ่งแคชไว้เป็นระยะๆ ในระหว่างการบำรุงรักษาเมื่อไม่มีการใช้งานเพื่อป้องกันการใช้พื้นที่เก็บข้อมูลมากเกินไป
  • ความพร้อมใช้งานในอุปกรณ์: การแปลงไฟล์ในเครื่องมือเลือกรูปภาพใช้ได้ใน Android 13 (ระดับ API 33) ขึ้นไป
  • การผสานรวมกิจกรรม AndroidX: ตรวจสอบว่าคุณใช้ไลบรารี AndroidX Activity เวอร์ชัน 1.11.0-alpha01 หรือเวอร์ชันอัลฟ่า/เบต้า/RC/เสถียรที่ใหม่กว่า เนื่องจากมี API setMediaCapabilitiesForTranscoding ที่จำเป็น