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

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

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

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

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

ใช้สัญญาของกิจกรรม Jetpack

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

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

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

เลือกรายการสื่อรายการเดียว

หากต้องการเลือกรายการสื่อรายการเดียว ให้ใช้สัญญาผลลัพธ์ของกิจกรรม 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 เวอร์ชัน 1.11.0-alpha01 หรือเวอร์ชันอัลฟ่า/เบต้า/RC/เสถียรที่ใหม่กว่า เนื่องจาก เวอร์ชันนี้มี setMediaCapabilitiesForTranscoding API ที่จำเป็น