يوفّر مقدّم خدمات الوسائط في السحابة الإلكترونية محتوًى إضافيًا من الوسائط في السحابة الإلكترونية إلى أداة اختيار الصور على Android. ويمكن للمستخدمين اختيار الصور أو الفيديوهات التي يوفّرها مقدّم خدمات الوسائط في السحابة الإلكترونية عندما يستخدم التطبيق ACTION_PICK_IMAGES
أو ACTION_GET_CONTENT
لطلب ملفات الوسائط من المستخدم. كما يمكن لمقدّم وسائط السحابة الإلكترونية تقديم معلومات حول الألبومات التي يمكن تصفّحها في "أداة اختيار الصور" على Android.
قبل البدء
ضع العناصر التالية في الاعتبار قبل البدء في إنشاء مزود وسائط السحابة.
الأهلية
يشغِّل Android برنامجًا تجريبيًا للسماح للتطبيقات التي تم ترشيحها من قِبل المصنّع الأصلي للجهاز بأن تصبح مقدّمي خدمات وسائط على السحابة الإلكترونية. التطبيقات التي يرشّحها المصنّعون الأصليون للأجهزة فقط مؤهّلة للمشاركة في هذا البرنامج لتصبح مقدّم وسائط سحابية لنظام Android في الوقت الحالي. ويمكن لكل مصنّع أصلي للجهاز ترشيح ما يصل إلى 3 تطبيقات. بعد الموافقة على هذه التطبيقات، سيصبح بإمكانها الوصول إليها كمزوّدي وسائط سحابة إلكترونية على أي جهاز "خدمات Google للأجهزة الجوّالة" (GMS) تم تثبيت هذه التطبيقات عليه.
يحتفظ Android بقائمة من جانب الخادم تضم جميع مقدّمي خدمات السحابة الإلكترونية المؤهَّلين. ويمكن لكل مصنّع أصلي للجهاز اختيار مقدّم خدمات سحابة إلكترونية تلقائي باستخدام تراكب قابل للتهيئة. ويجب أن تستوفي التطبيقات المرشَّحة جميع المتطلبات الفنية وأن تجتاز جميع اختبارات الجودة. لمعرفة المزيد حول عملية البرنامج التجريبي لمزوّد خدمات الوسائط السحابية لدى المصنّع الأصلي للجهاز ومتطلباته، يُرجى ملء نموذج الاستفسار.
تحديد ما إذا كنت بحاجة إلى إنشاء مقدّم خدمات وسائط في السحابة الإلكترونية
تم تصميم مقدّمي خدمات الوسائط السحابية ليكونوا تطبيقات أو خدمات تعمل كمصدر أساسي للمستخدمين للاحتفاظ بنسخة احتياطية من الصور والفيديوهات واستردادها من السحابة. إذا كان تطبيقك يحتوي على مكتبة من المحتوى المفيد، ولكن لا يتم استخدامها عادةً كحل لتخزين الصور، يجب عليك إنشاء موفِّر مستندات بدلاً من ذلك.
مقدّم خدمات سحابة إلكترونية نشط واحد لكل ملف تجاري
يمكن أن يكون هناك مقدّم وسائط نشط واحد على الأكثر في السحابة الإلكترونية في كل مرة لكل ملف شخصي على Android. يمكن للمستخدمين إزالة أو تغيير التطبيق المحدّد لمقدّم خدمة الوسائط السحابية في أي وقت من خلال إعدادات "أداة اختيار الصور".
سيحاول "أداة اختيار الصور" على Android اختيار مقدّم خدمات السحابة الإلكترونية تلقائيًا.
- إذا كان هناك مقدّم خدمات سحابية مؤهل واحد فقط على الجهاز، سيتم تلقائيًا اختيار هذا التطبيق كمقدّم خدمات حالي.
إذا كان هناك أكثر من مقدّم خدمات سحابة إلكترونية مؤهَّل واحد على الجهاز وكان أحدهم يتطابق مع الخيار التلقائي الذي اختاره المصنّع الأصلي للجهاز، سيتم اختيار التطبيق الذي يختاره المصنّع الأصلي للجهاز.
إذا كان هناك أكثر من مقدّم خدمات سحابة إلكترونية مؤهَّل واحد على الجهاز، ولم يتطابق أي منهم مع الخيار التلقائي الذي اختاره المصنّع الأصلي للجهاز، لن يتم اختيار أي تطبيق.
إنشاء مقدّم خدمات الوسائط في السحابة الإلكترونية
يوضِّح المخطّط التالي تسلسل الأحداث قبل وأثناء جلسة اختيار الصور بين تطبيق Android وأداة اختيار الصور من Android وMediaProvider
على الجهاز المحلي وCloudMediaProvider
.
- يبدأ النظام إعداد السحابة الإلكترونية المفضّل لدى المستخدم ويزامن بشكل دوري البيانات الوصفية للوسائط مع الواجهة الخلفية لأداة اختيار الصور على Android.
- عندما يشغِّل أحد تطبيقات Android "أداة اختيار الصور"، قبل عرض شبكة عناصر محلية أو مدمجة على السحابة الإلكترونية للمستخدم، تُجري "أداة اختيار الصور" مزامنة متزايدة حساسة لوقت الاستجابة مع مقدّم خدمات السحابة الإلكترونية لضمان عرض أحدث النتائج قدر الإمكان. بعد تلقّي رد أو عند انقضاء الموعد النهائي، تعرض شبكة أداة اختيار الصور الآن جميع الصور التي يمكن الوصول إليها، حيث تجمع تلك الصور المخزنة محليًا على جهازك مع الصور التي تمت مزامنتها من السحابة الإلكترونية.
- أثناء قيام المستخدم بالتمرير، يجلب "أداة اختيار الصور" الصور المصغّرة للوسائط من مقدّم خدمة الوسائط في السحابة الإلكترونية لعرضها في واجهة المستخدم.
- عندما يُكمل المستخدم الجلسة وتكون النتائج تتضمّن عنصر وسائط سحابية، يطلب منتقي الصور واصفات الملفات للمحتوى، وينشئ معرّف موارد منتظمًا، ويمنح تطبيق الاتصال إمكانية الوصول إلى الملف.
- يمكن للتطبيق الآن فتح معرّف الموارد المنتظم (URI) والوصول إلى محتوى الوسائط بالقراءة فقط. يتم تلقائيًا إخفاء البيانات الوصفية الحسّاسة. تستفيد أداة اختيار الصور من نظام ملفات FUSE لتنسيق تبادل البيانات بين تطبيق Android وموفِّر خدمة الوسائط على السحابة الإلكترونية.
المشاكل الشائعة
فيما يلي بعض الاعتبارات المهمة التي يجب وضعها في الاعتبار عند النظر في التنفيذ الخاص بك:
تجنب الملفات المكررة
بما أنّ "أداة اختيار الصور" على Android لا تتوفّر لها أي طريقة لفحص حالة الوسائط على السحابة الإلكترونية، يحتاج CloudMediaProvider
إلى توفير MEDIA_STORE_URI
في صف المؤشر لأي ملف متوفّر على السحابة الإلكترونية وعلى الجهاز المحلي، وإلا سيرى المستخدم ملفات مكرّرة في "أداة اختيار الصور".
تحسين أحجام الصور لعرض المعاينة
من المهم جدًا ألا يكون الملف الذي يتم عرضه من onOpenPreview
بالدقة الكاملة، وأن يتوافق مع Size
المطلوبة. ستستغرق الصورة الكبيرة جدًا أوقات تحميل في واجهة المستخدم، وقد تتقطّع الصورة الصغيرة جدًا أو تكون غير واضحة بناءً على حجم شاشة الجهاز.
التعامل مع الاتجاه الصحيح
إذا كانت الصور المصغّرة التي تم عرضها في onOpenPreview
لا تحتوي على بيانات EXIF، يجب عرضها بالاتجاه الصحيح لتجنُّب تدوير الصور المصغّرة
على نحو غير صحيح في شبكة المعاينة.
منع الوصول غير المصرّح به
ابحث عن MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION
قبل عرض البيانات للمتصل من ContentProvider. سيؤدي ذلك إلى منع التطبيقات غير المُصرَّح لها
من الوصول إلى البيانات السحابية.
فئة CloudMediaProvider
تشتمل الفئة CloudMediaProvider
المشتقة من android.content.ContentProvider
، على طُرق مثل تلك المعروضة في المثال التالي:
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()
لتقييم صلاحية عناصر الوسائط في السحابة الإلكترونية المخزَّنة مؤقتًا وتحديد المزامنة اللازمة مع مقدّم خدمة الوسائط في السحابة الإلكترونية. نظرًا لاحتمالية تلقّي طلبات متكررة من نظام التشغيل، يُعتبر 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
التي تم إرجاعها على الثبات التالية:
EXTRA_ALBUM_ID
EXTRA_LOOPING_PLAYBACK_ENABLED
EXTRA_MEDIA_COLLECTION_ID
EXTRA_PAGE_SIZE
EXTRA_PAGE_TOKEN
EXTRA_PREVIEW_THUMBNAIL
EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED
EXTRA_SYNC_GENERATION
MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION
PROVIDER_INTERFACE
على مقدّم خدمات الوسائط السحابية ضبط
CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID
كجزء من
Bundle
التي يتم عرضها. يُعد عدم ضبط ذلك خطأً ويؤدي إلى إلغاء صلاحية Cursor
التي تم عرضها. إذا
تعامل مقدّم خدمات الوسائط السحابية مع أي فلاتر في العناصر الإضافية المتوفرة، عليه إضافة
المفتاح إلى ContentResolver#EXTRA_HONORED_ARGS
كجزء من Cursor#setExtras
التي يتم عرضها.
onQueryDeletedMedia
يتم استخدام طريقة onQueryDeletedMedia()
لضمان إزالة العناصر المحذوفة في الحساب السحابي بشكل صحيح من واجهة مستخدم "أداة اختيار الصور". وبسبب حساسية وقت الاستجابة المحتملة، يمكن بدء هذه الطلبات كجزء من:
- المزامنة الاستباقية في الخلفية
- جلسات أداة اختيار الصور (عندما تكون حالة المزامنة الكاملة أو التزايدية مطلوبة)
تمنح واجهة المستخدم في "أداة اختيار الصور" الأولوية لتجربة المستخدم المتجاوبة مع مختلف الأجهزة،
ولن يتم الانتظار إلى أجل غير مسمى لتلقّي رد. للحفاظ على تفاعلات سلسة،
قد تحدث مهلات. وستحاول معالجة أي قيمة Cursor
تم إرجاعها في قاعدة بيانات أداة اختيار الصور خلال الجلسات المستقبلية.
تعرض هذه الطريقة Cursor
الذي يمثّل جميع ملفات الوسائط المحذوفة
في مجموعة الوسائط بالكامل ضمن إصدار مقدّم الخدمة الحالي كما يعرضها
onGetMediaCollectionInfo()
. يمكن فلترة هذه العناصر حسب الميزات الإضافية اختياريًا.
على مقدّم خدمة الوسائط السحابية ضبط
CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID
كجزء من البيانات التي يتم عرضها.
Cursor#setExtras
في حال عدم ضبط هذا، يتم اعتبار أنّ هذا خطأ يؤدي إلى إلغاء صلاحية Cursor
. إذا
تعامل موفّر الخدمة مع أي فلاتر في الإضافات المتوفرة، عليه إضافة المفتاح إلى ContentResolver#EXTRA_HONORED_ARGS
.
onQueryAlbums
يتم استخدام طريقة onQueryAlbums()
لجلب قائمة بألبومات السحابة الإلكترونية
المتاحة لدى مقدّم خدمات السحابة الإلكترونية والبيانات الوصفية المرتبطة بها. يمكنك الاطّلاع على
CloudMediaProviderContract.AlbumColumns
للحصول على تفاصيل إضافية.
تعرض هذه الطريقة علامة Cursor
التي تمثّل جميع عناصر الألبوم في مجموعة الوسائط
التي تتم فلترتها بشكل اختياري حسب الميزات الإضافية المتوفّرة ويتم ترتيبها بترتيب زمني
عكسي حسب AlbumColumns#DATE_TAKEN_MILLIS
، وهي أحدث العناصر
أولاً. على مقدّم خدمات الوسائط السحابية ضبط
CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID
كجزء من
Cursor
التي يتم عرضها. يُعد عدم ضبط ذلك خطأً ويؤدي إلى إلغاء صلاحية Cursor
التي تم عرضها. إذا
تعامل المزوّد مع أي فلاتر في الإضافات المتوفرة، عليه إضافة المفتاح إلى ContentResolver#EXTRA_HONORED_ARGS
كجزء من Cursor
التي يتم عرضها.
على OpenMedia
من المفترض أن تعرض الطريقة onOpenMedia()
الوسائط بالحجم الكامل المحدّدة من خلال
السمة mediaId
المتوفرة. إذا تم حظر هذه الطريقة أثناء تنزيل المحتوى على الجهاز، يجب التحقق بشكل دوري من علامة CancellationSignal
المتوفرة لإلغاء الطلبات التي تم التخلي عنها.
onOpenPreview
من المفترض أن تعرض الطريقة onOpenPreview()
صورة مصغّرة من size
المتوفرة لعنصر رقم تعريف الوسائط المقدَّم. يجب أن تكون الصورة المصغّرة بتنسيق CloudMediaProviderContract.MediaColumns#MIME_TYPE
الأصلي، ومن المتوقّع أن تكون درجة دقة الصورة المصغّرة أقل بكثير من جودة الصورة التي يعرضها onOpenMedia
. إذا تم حظر هذه الطريقة
أثناء تنزيل المحتوى على الجهاز، عليك التحقق بشكل دوري
من علامة CancellationSignal
المتوفرة لإلغاء الطلبات التي تم إلغاؤها.
وحدة تحكم onCreateCloudMediaSurfaceController
من المفترض أن تعرض طريقة onCreateCloudMediaSurfaceController()
القيمة CloudMediaSurfaceController
المستخدمة لعرض معاينة عناصر الوسائط أو null
إذا كان عرض المعاينة غير متوافق.
يدير CloudMediaSurfaceController
عرض معاينة عناصر الوسائط
على مثيلات معيّنة من Surface
. ومن المفترض أن تكون الطرق ضمن هذه الفئة غير متزامنة، ويجب ألا يتم حظرها من خلال تنفيذ أي عملية صعبة. ويكون مثيل CloudMediaSurfaceController
الواحد مسؤولاً عن عرض عناصر
وسائط متعددة مرتبطة بمساحات عرض متعددة.
تتوافق "CloudMediaSurfaceController
" مع القائمة التالية من عمليات معاودة الاتصال بمراحل النشاط:
onConfigChange
onDestroy
onMediaPause
onMediaPlay
onMediaSeekTo
onPlayerCreate
onPlayerRelease
onSurfaceChanged
onSurfaceCreated
onSurfaceDestroyed