أداة اختيار الصور

يظهر مربّع حوار "أداة اختيار الصور" مع ملفات الوسائط على جهازك. اختَر صورة لمشاركتها مع التطبيق.
الشكل 1. توفّر "أداة اختيار الصور" واجهة مستخدم سهلة الاستخدام لمشاركة الصور مع تطبيقك.

توفّر أداة اختيار الصور واجهة قابلة للتصفّح تعرض للمستخدم مكتبة الوسائط الخاصة به، ويتم ترتيبها حسب التاريخ من الأحدث إلى الأقدم. كما هو موضّح في الدليل التعليمي حول أفضل الممارسات المتعلقة بالخصوصية، توفّر أداة اختيار الصور طريقة آمنة ومضمّنة للمستخدمين من أجل منح تطبيقك إذن الوصول إلى صور وفيديوهات محدّدة فقط بدلاً من الوصول إلى مكتبة الوسائط بأكملها.

يمكن للمستخدمين الذين لديهم مقدّمو خدمات وسائط مؤهّلون على السحابة الإلكترونية على أجهزتهم أيضًا الاختيار من بين الصور والفيديوهات المخزّنة عن بُعد. مزيد من المعلومات عن موفّري الوسائط في السحابة الإلكترونية

ويتم تحديث الأداة تلقائيًا لتوفير الكثير من الوظائف لمستخدمي التطبيق بمرور الوقت بدون الحاجة إلى إجراء أي تغييرات على الرموز.

استخدام عقود نشاط Jetpack

ولتبسيط عملية دمج أداة اختيار الصور، يجب تضمين الإصدار 1.7.0 أو الإصدارات الأحدث من مكتبة androidx.activity.

استخدِم عقود نتائج الأنشطة التالية لتشغيل أداة اختيار الصور:

إذا لم تكن أداة اختيار الصور متاحة على أحد الأجهزة، ستستدعي المكتبة تلقائيًا إجراء الإجراء المقصود ACTION_OPEN_DOCUMENT بدلاً من ذلك. يتوفّر هذا الإجراء على الأجهزة التي تعمل بنظام التشغيل Android 4.4 (مستوى واجهة برمجة التطبيقات 19) أو إصدار أحدث. يمكنك التحقّق مما إذا كان تطبيق "أداة اختيار الصور" متوفّرًا على جهاز معيّن من خلال الاتصال بالرقم 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 (المستوى 19 من واجهة برمجة التطبيقات) إلى الإصدار 10 (المستوى 29 من واجهة برمجة التطبيقات) وأجهزة Android Go التي تعمل بالإصدار 11 أو 12 من نظام التشغيل ذاته والمتوافقة مع "خدمات Google Play". ل تفعيل التثبيت التلقائي لمكوّن "أداة اختيار الصور" المتوافقة مع الإصدارات القديمة من Android من خلال "خدمات Google Play"، أضِف الإدخال التالي إلى علامة <application> في ملف بيان تطبيقك:

<!-- 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) باستخدام ميزة تحويل الترميز

وفّر الإصدار 13 من نظام التشغيل Android (المستوى 33 لواجهة برمجة التطبيقات) إمكانية تصوير فيديوهات بنطاق عالي الديناميكية (HDR). على الرغم من أنّ تقنية HDR تقدّم تجربة مرئية أكثر ثراءً، قد لا تكون بعض التطبيقات القديمة مجهّزة للتعامل مع هذه التنسيقات الجديدة، ما يؤدي إلى حدوث مشاكل مثل عرض ألوان غير طبيعية أثناء التشغيل (مثل الوجوه ذات اللون الأخضر). للتغلب على هذه المشكلة في التوافق، يوفّر "أداة اختيار الصور" ميزة تحويل ترميز يمكنها تحويل الفيديوهات بنطاق عالي الديناميكية تلقائيًا إلى تنسيق النطاق الديناميكي العادي (SDR) قبل إرسالها إلى التطبيق الذي طلبها.

يتمثل الهدف الأساسي من تحويل ترميز "أداة اختيار الصور" في ضمان تجربة وسائط متّسقة وermatدقة من الناحية المرئية على نطاق أوسع من التطبيقات، حتى التطبيقات التي لا تتيح استخدام تقنية النطاق العالي الديناميكية (HDR) بعد. من خلال تحويل الفيديوهات ذات النطاق العالي الديناميكية إلى فيديوهات ذات نطاق ديناميكي عادي،تهدف أداة اختيار الصور إلى تحسين توافق التطبيق وتقديم تجربة استخدام سلسة.

آلية عمل تحويل ترميز "أداة اختيار الصور"

لا يتم تفعيل تحويل ترميز HDR في "أداة اختيار الصور" تلقائيًا. لتفعيل هذه الميزة، يجب أن يعلن تطبيقك صراحةً عن إمكانات معالجة تنسيقات الوسائط عند تشغيل أداة اختيار الصور.

يقدّم تطبيقك إمكانات معالجة الوسائط إلى أداة اختيار الصور. ويتم ذلك عند تشغيل أداة اختيار الصور باستخدام مكتبة الأنشطة في AndroidX من خلال إضافة mediaCapabilities إلى PickVisualMediaRequest.Builder. تمت إضافة واجهة برمجة تطبيقات جديدة، setMediaCapabilitiesForTranscoding(capabilities: MediaCapabilities?)، إلى PickVisualMediaRequest.Builder لتسهيل ذلك.

يمكنك التحكّم في سلوك تحويل ترميز HDR باستخدام فئة MediaCapabilities. قدِّم عنصر MediaCapabilities يحدِّد أنواع HDR التي يقبلها تطبيقك تحديدًا (مثل TYPE_HLG10 وTYPE_HDR10 وTYPE_HDR10_PLUS TYPE_DOLBY_VISION).

لإيقاف تحويل الترميز بالكامل، أرسِل القيمة null بدلاً من MediaCapabilities. سيتم اعتبار أي نوع من أنواع HDR غير مُدرَج صراحةً في الإمكانات المقدَّمة غير متوافق. تتوفّر واجهة برمجة التطبيقات هذه على Android 13 (المستوى 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

  • الأداء ومساحة التخزين: تستغرق عملية تحويل الترميز وقتًا في المعالجة وتؤدي إلى إنشاءملف جديد يستهلك مساحة تخزين.
  • الحد الأقصى لمدة الفيديو: لتحقيق التوازن بين تجربة المستخدم والقيود المفروضة على مساحة التخزين، يُسمح بمدة فيديو لا تتجاوز دقيقة واحدة.
  • إدارة الملفات المخزّنة مؤقتًا: يتم محو الملفات المحوَّلة التي تم تخزينها مؤقتًا بشكل دوري أثناء عمليات الصيانة في وضع السكون لمنع استخدام مساحة تخزين زائدة.
  • الأجهزة المتوافقة: تتوفّر ميزة تحويل ترميز "أداة اختيار الصور" على Android 13 (المستوى 33 لواجهة برمجة التطبيقات) والإصدارات الأحدث.
  • دمج الأنشطة في AndroidX: تأكَّد من استخدام الإصدار 1.11.0-alpha01 أو إصدارًا أحدث من الإصدارات التجريبية/الإصدارات التجريبية/الإصدارات التجريبية العلنية/الإصدارات الثابتة من مكتبة الأنشطة في AndroidX، لأنّه يتضمّن واجهة برمجة التطبيقات setMediaCapabilitiesForTranscoding اللازمة.