สร้างผู้ให้บริการสื่อในระบบคลาวด์สำหรับ Android

ผู้ให้บริการสื่อในระบบคลาวด์ให้บริการเนื้อหาสื่อในระบบคลาวด์เพิ่มเติมแก่ เครื่องมือเลือกรูปภาพ ผู้ใช้สามารถเลือกรูปภาพหรือวิดีโอที่ส่งมาจาก ผู้ให้บริการสื่อในระบบคลาวด์เมื่อแอปใช้ ACTION_PICK_IMAGES หรือ ACTION_GET_CONTENT เพื่อขอไฟล์สื่อจากผู้ใช้ สื่อในระบบคลาวด์ ยังสามารถให้ข้อมูลเกี่ยวกับอัลบั้ม ซึ่งสามารถเรียกดูใน เครื่องมือเลือกรูปภาพของ Android

ก่อนเริ่มต้น

คำนึงถึงสิ่งต่อไปนี้ก่อนเริ่มสร้างระบบคลาวด์ ของผู้ให้บริการสื่อ

การมีสิทธิ์

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

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

ตัดสินใจว่าจะสร้างผู้ให้บริการสื่อในระบบคลาวด์หรือไม่

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

ผู้ให้บริการระบบคลาวด์ที่ใช้งานอยู่ 1 รายต่อโปรไฟล์

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

โดยค่าเริ่มต้น เครื่องมือเลือกรูปภาพของ Android จะพยายามเลือกผู้ให้บริการคลาวด์ โดยอัตโนมัติ

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

  • หากมีผู้ให้บริการระบบคลาวด์ที่มีสิทธิ์มากกว่า 1 รายในอุปกรณ์ และไม่มี ตรงกับค่าเริ่มต้นที่ OEM เลือกไว้ ระบบจะไม่เลือกแอปใดๆ

สร้างผู้ให้บริการสื่อในระบบคลาวด์

แผนภาพต่อไปนี้แสดงลำดับของเหตุการณ์ทั้งในช่วงก่อนและระหว่าง เซสชันการเลือกรูปภาพระหว่างแอป Android เครื่องมือเลือกรูปภาพของ Android MediaProviderของอุปกรณ์ในเครือข่ายเดียวกันและCloudMediaProvider

วันที่ แผนภาพลำดับแสดงโฟลว์จากการเลือกรูปภาพไปยังผู้ให้บริการสื่อในระบบคลาวด์
ภาพที่ 1: แผนภาพลำดับเหตุการณ์ระหว่างเซสชันการเลือกรูปภาพ
  1. ระบบจะเริ่มต้นผู้ให้บริการคลาวด์ที่ผู้ใช้ต้องการเป็นระยะๆ ซิงค์ข้อมูลเมตาของสื่อกับแบ็กเอนด์เครื่องมือเลือกรูปภาพของ Android
  2. เมื่อแอป Android เปิดตัวเลือกรูปภาพ ก่อนแสดงรูปภาพในเครื่องที่ผสานรวม หรือตารางรายการในระบบคลาวด์ของผู้ใช้ เครื่องมือเลือกรูปภาพจะดำเนินการควบคุมเวลาในการตอบสนอง การซิงค์เพิ่มขึ้นกับผู้ให้บริการคลาวด์เพื่อให้ผลลัพธ์เป็นปัจจุบัน ให้มากที่สุด หลังจากได้รับการตอบกลับหรือเมื่อถึงกำหนดเวลา ตารางเครื่องมือเลือกรูปภาพจะแสดงรูปภาพที่สามารถเข้าถึงได้ทั้งหมด รวมถึงรูปภาพที่เก็บไว้ ในอุปกรณ์ของคุณกับรายการที่ซิงค์จากระบบคลาวด์
  3. ขณะที่ผู้ใช้เลื่อน เครื่องมือเลือกรูปภาพจะดึงภาพขนาดย่อของสื่อจาก ของผู้ให้บริการสื่อระบบคลาวด์ เพื่อแสดงใน UI
  4. เมื่อผู้ใช้จบเซสชันและผลลัพธ์มีสื่อในระบบคลาวด์ เครื่องมือเลือกรูปภาพจะส่งคำขอคำอธิบายไฟล์สำหรับเนื้อหา และสร้าง URI และให้สิทธิ์เข้าถึงไฟล์แก่แอปพลิเคชันการเรียกใช้
  5. ตอนนี้แอปสามารถเปิด URI และมีสิทธิ์เข้าถึงสื่อแบบอ่านอย่างเดียว เนื้อหา โดยค่าเริ่มต้น ข้อมูลเมตาที่ละเอียดอ่อนจะได้รับการปกปิด เครื่องมือเลือกรูปภาพ ใช้ประโยชน์จากระบบไฟล์ FUSE เพื่อประสานงานการแลกเปลี่ยนข้อมูลระหว่าง แอป Android และผู้ให้บริการสื่อในระบบคลาวด์

ปัญหาทั่วไป

ข้อควรพิจารณาที่สำคัญบางประการที่ควรคำนึงถึงเมื่อพิจารณา การใช้งาน:

หลีกเลี่ยงไฟล์ที่ซ้ำกัน

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

เพิ่มประสิทธิภาพขนาดรูปภาพสําหรับการแสดงตัวอย่าง

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

จัดการกับการวางแนวที่ถูกต้อง

หากภาพขนาดย่อที่แสดงใน onOpenPreview ไม่มีข้อมูล EXIF ภาพ ควรส่งคืนในการวางแนวที่ถูกต้องเพื่อหลีกเลี่ยงไม่ให้ภาพขนาดย่อถูกหมุน ในตารางตัวอย่างไม่ถูกต้อง

ป้องกันการเข้าถึงที่ไม่ได้รับอนุญาต

ตรวจสอบ MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION ก่อนส่งคืนข้อมูล จาก ContentProvider วิธีนี้จะป้องกันไม่ให้แอปที่ไม่ได้รับอนุญาต เข้าถึงข้อมูลในระบบคลาวด์

คลาส CloudMediaProvider

มาจาก android.content.ContentProvider ซึ่งเป็น CloudMediaProvider มีเมธอดเช่นเดียวกับที่แสดงในตัวอย่างต่อไปนี้:

Kotlin

abstract class CloudMediaProvider : ContentProvider() {

    @NonNull
    abstract override fun onGetMediaCollectionInfo(@NonNull bundle: Bundle): Bundle

    @NonNull
    override fun onQueryAlbums(@NonNull bundle: Bundle): Cursor = TODO("Implement onQueryAlbums")

    @NonNull
    abstract override fun onQueryDeletedMedia(@NonNull bundle: Bundle): Cursor

    @NonNull
    abstract override fun onQueryMedia(@NonNull bundle: Bundle): Cursor

    @NonNull
    abstract override fun onOpenMedia(
        @NonNull string: String,
        @Nullable bundle: Bundle?,
        @Nullable cancellationSignal: CancellationSignal?
    ): ParcelFileDescriptor

    @NonNull
    abstract override fun onOpenPreview(
        @NonNull string: String,
        @NonNull point: Point,
        @Nullable bundle: Bundle?,
        @Nullable cancellationSignal: CancellationSignal?
    ): AssetFileDescriptor

    @Nullable
    override fun onCreateCloudMediaSurfaceController(
        @NonNull bundle: Bundle,
        @NonNull callback: CloudMediaSurfaceStateChangedCallback
    ): CloudMediaSurfaceController? = null
}

Java

public abstract class CloudMediaProvider extends android.content.ContentProvider {

  @NonNull
  public abstract android.os.Bundle onGetMediaCollectionInfo(@NonNull android.os.Bundle);

  @NonNull
  public android.database.Cursor onQueryAlbums(@NonNull android.os.Bundle);

  @NonNull
  public abstract android.database.Cursor onQueryDeletedMedia(@NonNull android.os.Bundle);

  @NonNull
  public abstract android.database.Cursor onQueryMedia(@NonNull android.os.Bundle);

  @NonNull
  public abstract android.os.ParcelFileDescriptor onOpenMedia(@NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;

  @NonNull
  public abstract android.content.res.AssetFileDescriptor onOpenPreview(@NonNull String, @NonNull android.graphics.Point, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;

  @Nullable
  public android.provider.CloudMediaProvider.CloudMediaSurfaceController onCreateCloudMediaSurfaceController(@NonNull android.os.Bundle, @NonNull android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback);
}

คลาส CloudMediaProviderContract

นอกเหนือจากคลาสการใช้งาน CloudMediaProvider หลักแล้ว ฟังก์ชัน เครื่องมือเลือกรูปภาพของ Android มีคลาส CloudMediaProviderContract รวมอยู่ด้วย คลาสนี้จะอธิบายความสามารถในการทำงานร่วมกันระหว่างเครื่องมือเลือกรูปภาพกับระบบคลาวด์ ของผู้ให้บริการสื่อต่างๆ ซึ่งรวมถึงด้านต่างๆ เช่น MediaCollectionInfo สำหรับ การดำเนินการซิงค์ข้อมูล คาดไว้ Cursor คอลัมน์ และรายการเพิ่มเติม Bundle รายการ

Kotlin

object CloudMediaProviderContract {

    const val EXTRA_ALBUM_ID = "android.provider.extra.ALBUM_ID"
    const val EXTRA_LOOPING_PLAYBACK_ENABLED = "android.provider.extra.LOOPING_PLAYBACK_ENABLED"
    const val EXTRA_MEDIA_COLLECTION_ID = "android.provider.extra.MEDIA_COLLECTION_ID"
    const val EXTRA_PAGE_SIZE = "android.provider.extra.PAGE_SIZE"
    const val EXTRA_PAGE_TOKEN = "android.provider.extra.PAGE_TOKEN"
    const val EXTRA_PREVIEW_THUMBNAIL = "android.provider.extra.PREVIEW_THUMBNAIL"
    const val EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED = "android.provider.extra.SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED"
    const val EXTRA_SYNC_GENERATION = "android.provider.extra.SYNC_GENERATION"
    const val MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION = "com.android.providers.media.permission.MANAGE_CLOUD_MEDIA_PROVIDERS"
    const val PROVIDER_INTERFACE = "android.content.action.CLOUD_MEDIA_PROVIDER"

    object MediaColumns {
        const val DATE_TAKEN_MILLIS = "date_taken_millis"
        const val DURATION_MILLIS = "duration_millis"
        const val HEIGHT = "height"
        const val ID = "id"
        const val IS_FAVORITE = "is_favorite"
        const val MEDIA_STORE_URI = "media_store_uri"
        const val MIME_TYPE = "mime_type"
        const val ORIENTATION = "orientation"
        const val SIZE_BYTES = "size_bytes"
        const val STANDARD_MIME_TYPE_EXTENSION = "standard_mime_type_extension"
        const val STANDARD_MIME_TYPE_EXTENSION_ANIMATED_WEBP = 3 // 0x3
        const val STANDARD_MIME_TYPE_EXTENSION_GIF = 1 // 0x1
        const val STANDARD_MIME_TYPE_EXTENSION_MOTION_PHOTO = 2 // 0x2
        const val STANDARD_MIME_TYPE_EXTENSION_NONE = 0 // 0x0
        const val SYNC_GENERATION = "sync_generation"
        const val WIDTH = "width"
    }

    object AlbumColumns {
        const val DATE_TAKEN_MILLIS = "date_taken_millis"
        const val DISPLAY_NAME = "display_name"
        const val ID = "id"
        const val MEDIA_COUNT = "album_media_count"
        const val MEDIA_COVER_ID = "album_media_cover_id"
    }

    object MediaCollectionInfo {
        const val ACCOUNT_CONFIGURATION_INTENT = "account_configuration_intent"
        const val ACCOUNT_NAME = "account_name"
        const val LAST_MEDIA_SYNC_GENERATION = "last_media_sync_generation"
        const val MEDIA_COLLECTION_ID = "media_collection_id"
    }
}

Java

public final class CloudMediaProviderContract {

  public static final String EXTRA_ALBUM_ID = "android.provider.extra.ALBUM_ID";
  public static final String EXTRA_LOOPING_PLAYBACK_ENABLED = "android.provider.extra.LOOPING_PLAYBACK_ENABLED";
  public static final String EXTRA_MEDIA_COLLECTION_ID = "android.provider.extra.MEDIA_COLLECTION_ID";
  public static final String EXTRA_PAGE_SIZE = "android.provider.extra.PAGE_SIZE";
  public static final String EXTRA_PAGE_TOKEN = "android.provider.extra.PAGE_TOKEN";
  public static final String EXTRA_PREVIEW_THUMBNAIL = "android.provider.extra.PREVIEW_THUMBNAIL";
  public static final String EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED = "android.provider.extra.SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED";
  public static final String EXTRA_SYNC_GENERATION = "android.provider.extra.SYNC_GENERATION";
  public static final String MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION = "com.android.providers.media.permission.MANAGE_CLOUD_MEDIA_PROVIDERS";
  public static final String PROVIDER_INTERFACE = "android.content.action.CLOUD_MEDIA_PROVIDER";
}

// Columns available for every media item
public static final class CloudMediaProviderContract.MediaColumns {

  public static final String DATE_TAKEN_MILLIS = "date_taken_millis";
  public static final String DURATION_MILLIS = "duration_millis";
  public static final String HEIGHT = "height";
  public static final String ID = "id";
  public static final String IS_FAVORITE = "is_favorite";
  public static final String MEDIA_STORE_URI = "media_store_uri";
  public static final String MIME_TYPE = "mime_type";
  public static final String ORIENTATION = "orientation";
  public static final String SIZE_BYTES = "size_bytes";
  public static final String STANDARD_MIME_TYPE_EXTENSION = "standard_mime_type_extension";
  public static final int STANDARD_MIME_TYPE_EXTENSION_ANIMATED_WEBP = 3; // 0x3
  public static final int STANDARD_MIME_TYPE_EXTENSION_GIF = 1; // 0x1 
  public static final int STANDARD_MIME_TYPE_EXTENSION_MOTION_PHOTO = 2; // 0x2 
  public static final int STANDARD_MIME_TYPE_EXTENSION_NONE = 0; // 0x0 
  public static final String SYNC_GENERATION = "sync_generation";
  public static final String WIDTH = "width";
}

// Columns available for every album item
public static final class CloudMediaProviderContract.AlbumColumns {

  public static final String DATE_TAKEN_MILLIS = "date_taken_millis";
  public static final String DISPLAY_NAME = "display_name";
  public static final String ID = "id";
  public static final String MEDIA_COUNT = "album_media_count";
  public static final String MEDIA_COVER_ID = "album_media_cover_id";
}

// Media Collection metadata that is cached by the OS to compare sync states.
public static final class CloudMediaProviderContract.MediaCollectionInfo {

  public static final String ACCOUNT_CONFIGURATION_INTENT = "account_configuration_intent";
  public static final String ACCOUNT_NAME = "account_name";
  public static final String LAST_MEDIA_SYNC_GENERATION = "last_media_sync_generation";
  public static final String MEDIA_COLLECTION_ID = "media_collection_id";
}

ข้อมูลคอลเล็กชันสื่อ

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

Kotlin

abstract fun onGetMediaCollectionInfo(extras: Bundle): Bundle

Java

@NonNull
public abstract Bundle onGetMediaCollectionInfo(@NonNull Bundle extras);

กลุ่ม MediaCollectionInfo ที่แสดงผลประกอบด้วยค่าคงที่ต่อไปนี้

onQueryMedia

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

วิธีนี้จะแสดง Cursor ที่แสดงรายการสื่อทั้งหมดในสื่อ คอลเล็กชันสามารถกรองได้ตามส่วนเพิ่มเติมที่ให้ไว้และจัดเรียงกลับกัน ตามลำดับเวลาของ MediaColumns#DATE_TAKEN_MILLIS (รายการล่าสุด ก่อน)

แพ็กเกจ CloudMediaProviderContract ที่ส่งคืนประกอบด้วย ค่าคงที่:

ผู้ให้บริการสื่อในระบบคลาวด์จะต้องตั้งค่า CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID เป็นส่วนหนึ่งของสินค้าที่ส่งคืน Bundle การไม่ตั้งค่านี้เป็นข้อผิดพลาดและทำให้ Cursor ที่แสดงผลเป็นโมฆะ ถ้า ผู้ให้บริการสื่อในระบบคลาวด์ได้จัดการตัวกรองใดๆ ในบริการเสริมที่มีให้ ระบบก็ต้องเพิ่ม คีย์ไปยัง ContentResolver#EXTRA_HONORED_ARGS เป็นส่วนหนึ่งของผลลัพธ์ Cursor#setExtras

ออนคำค้นหาลบสื่อ

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

  • การซิงค์ข้อมูลเชิงรุกในเบื้องหลัง
  • เซสชันเครื่องมือเลือกรูปภาพ (เมื่อต้องมีสถานะการซิงค์แบบเต็มหรือเพิ่มขึ้น)

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

วิธีนี้จะแสดง Cursor ที่แสดงรายการสื่อทั้งหมดที่ถูกลบใน คอลเล็กชันสื่อทั้งหมดภายในเวอร์ชันปัจจุบันของผู้ให้บริการปัจจุบันที่แสดงผลโดย onGetMediaCollectionInfo() คุณเลือกกรองรายการเหล่านี้ตามรายการเพิ่มเติมได้ ผู้ให้บริการสื่อในระบบคลาวด์ต้องตั้งค่า CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID เป็นส่วนหนึ่งของสินค้าที่ส่งคืน Cursor#setExtras การไม่ตั้งค่านี้เป็นข้อผิดพลาดและทำให้ Cursor เป็นโมฆะ ถ้า ผู้ให้บริการได้จัดการกับตัวกรองในส่วนเพิ่มเติมที่มีให้ ผู้ให้บริการจะต้องเพิ่มคีย์ ContentResolver#EXTRA_HONORED_ARGS

onQueryอัลบั้ม

เมธอด onQueryAlbums() ใช้เพื่อดึงข้อมูลรายการอัลบั้มระบบคลาวด์ที่ พร้อมให้ใช้งานในผู้ให้บริการคลาวด์และข้อมูลเมตาที่เกี่ยวข้อง โปรดดู CloudMediaProviderContract.AlbumColumns เพื่อดูรายละเอียดเพิ่มเติม

วิธีนี้จะแสดง Cursor ที่แสดงรายการอัลบั้มทั้งหมดในสื่อ คอลเล็กชันสามารถกรองได้ตามส่วนเพิ่มเติมที่ให้ไว้และจัดเรียงกลับกัน ตามลำดับเวลาของ AlbumColumns#DATE_TAKEN_MILLIS รายการล่าสุด ก่อน ผู้ให้บริการสื่อในระบบคลาวด์ต้องตั้งค่า CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID เป็นส่วนหนึ่งของสินค้าที่ส่งคืน Cursor การไม่ตั้งค่านี้เป็นข้อผิดพลาดและทำให้ Cursor ที่แสดงผลเป็นโมฆะ ถ้า ผู้ให้บริการได้จัดการกับตัวกรองในส่วนเพิ่มเติมที่มีให้ ผู้ให้บริการจะต้องเพิ่มคีย์ ContentResolver#EXTRA_HONORED_ARGS เป็นส่วนหนึ่งของ Cursor ที่แสดงผล

onOpenMedia

เมธอด onOpenMedia() ควรแสดงสื่อขนาดเต็มที่ระบุโดย mediaId ที่ให้ไว้ หากวิธีนี้บล็อกขณะดาวน์โหลดเนื้อหาไปยัง คุณควรตรวจสอบอุปกรณ์ CancellationSignal ที่ระบุเป็นระยะๆ เพื่อล้มเลิก คำขอที่ละทิ้ง

เปิดOpenPreview

เมธอด onOpenPreview() ควรจะแสดงภาพขนาดย่อของเนื้อหาที่ระบุ size สำหรับรายการของรหัสสื่อที่ระบุ ภาพขนาดย่อควรอยู่ในรูปแบบ CloudMediaProviderContract.MediaColumns#MIME_TYPE เดิมและคาดว่าจะ มีความละเอียดต่ำกว่าสินค้าที่ onOpenMedia ส่งคืนมาก หากวิธีนี้ ถูกบล็อกขณะดาวน์โหลดเนื้อหาลงในอุปกรณ์ คุณควรเป็นระยะๆ ตรวจสอบ CancellationSignal ที่ให้ไว้เพื่อล้มเลิกคำขอที่ละทิ้ง

บนCreateCloudMediaSurfaceController

เมธอด onCreateCloudMediaSurfaceController() ควรแสดงผล CloudMediaSurfaceController ที่ใช้สำหรับแสดงผลตัวอย่างรายการสื่อ หรือ null หากระบบไม่รองรับการแสดงผลตัวอย่าง

CloudMediaSurfaceController จัดการการแสดงผลการแสดงตัวอย่างรายการสื่อ ในอินสแตนซ์ที่ระบุของ Surface วิธีการของชั้นเรียนนี้ควรเป็น อะซิงโครนัส และไม่ควรบล็อกโดยการทำงานหนักใดๆ คำขอ อินสแตนซ์ CloudMediaSurfaceController มีหน้าที่แสดงผลหลายรายการ รายการสื่อที่เชื่อมโยงกับหลายแพลตฟอร์ม

CloudMediaSurfaceController รองรับรายการต่อไปนี้ของ Lifecycle Callback: