انتخابگر عکس

کادر انتخاب عکس با فایل‌های رسانه‌ای روی دستگاه شما ظاهر می‌شود. عکسی را برای اشتراک‌گذاری با برنامه انتخاب کنید.
شکل ۱. انتخابگر عکس، یک رابط کاربری بصری برای اشتراک‌گذاری عکس‌ها با برنامه شما فراهم می‌کند.

انتخابگر عکس یک رابط کاربری قابل مرور ارائه می‌دهد که کتابخانه رسانه‌ای کاربر را که بر اساس تاریخ از جدیدترین به قدیمی‌ترین مرتب شده است، نمایش می‌دهد. همانطور که در codelab بهترین شیوه‌های حفظ حریم خصوصی نشان داده شده است، انتخابگر عکس روشی امن و داخلی برای کاربران فراهم می‌کند تا به برنامه شما اجازه دهند فقط به تصاویر و ویدیوهای انتخاب شده دسترسی داشته باشد، نه به کل کتابخانه رسانه‌ای خود.

کاربرانی که ارائه‌دهندگان رسانه‌های ابری واجد شرایط را روی دستگاه خود دارند، می‌توانند از عکس‌ها و ویدیوهای ذخیره شده از راه دور نیز انتخاب کنند. درباره ارائه‌دهندگان رسانه‌های ابری بیشتر بدانید .

این ابزار به طور خودکار به‌روزرسانی می‌شود و به مرور زمان و بدون نیاز به تغییر کد، قابلیت‌های بیشتری را در اختیار کاربران برنامه شما قرار می‌دهد.

از قراردادهای فعالیت Jetpack استفاده کنید

برای ساده‌سازی ادغام انتخابگر عکس، نسخه ۱.۷.۰ یا بالاتر از کتابخانه androidx.activity را اضافه کنید.

برای اجرای انتخابگر عکس، از قراردادهای نتیجه فعالیت زیر استفاده کنید:

اگر انتخابگر عکس در دستگاهی موجود نباشد، کتابخانه به طور خودکار اکشن اینتنت ACTION_OPEN_DOCUMENT فراخوانی می‌کند. این اینتنت در دستگاه‌هایی که اندروید ۴.۴ (سطح API ۱۹) یا بالاتر را اجرا می‌کنند، پشتیبانی می‌شود. می‌توانید با فراخوانی 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() را فراخوانی کنید. در دستگاه‌هایی که انتخابگر عکس پشتیبانی نمی‌شود، این محدودیت نادیده گرفته می‌شود.

در دسترس بودن دستگاه

انتخابگر عکس در دستگاه‌هایی که معیارهای زیر را دارند، موجود است:

دستگاه‌های قدیمی‌تر که اندروید ۴.۴ (API سطح ۱۹) تا اندروید ۱۰ (API سطح ۲۹) را اجرا می‌کنند و دستگاه‌های اندروید گو که اندروید ۱۱ یا ۱۲ را اجرا می‌کنند و از سرویس‌های گوگل پلی پشتیبانی می‌کنند، می‌توانند یک نسخه پشتیبان‌گیری شده از photo picker را نصب کنند. برای فعال کردن نصب خودکار ماژول پشتیبان‌گیری شده photo picker از طریق سرویس‌های گوگل پلی، ورودی زیر را به تگ <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() را فراخوانی کنید:

کاتلین

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

جاوا

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

مدیریت ویدیوهای HDR با استفاده از کدنویسی

اندروید ۱۳ (API 33) قابلیت ضبط ویدیوهای HDR (محدوده دینامیکی بالا) را معرفی کرد. در حالی که HDR تجربه بصری غنی‌تری ارائه می‌دهد، برخی از برنامه‌های قدیمی‌تر ممکن است برای مدیریت این فرمت‌های جدیدتر مجهز نباشند و منجر به مشکلاتی مانند نمایش رنگ غیرطبیعی در هنگام پخش (مانند چهره‌های سبز رنگ) شوند. برای رفع این شکاف سازگاری، انتخابگر عکس یک ویژگی تبدیل کد ارائه می‌دهد که می‌تواند ویدیوهای HDR را قبل از ارائه به برنامه درخواست‌کننده، به طور خودکار به فرمت SDR (محدوده دینامیکی استاندارد) تبدیل کند.

هدف اصلی تبدیل کد تصویر به فرمت SDR در Photo Picker، تضمین یک تجربه رسانه‌ای سازگار و بصری دقیق در طیف وسیع‌تری از برنامه‌ها، حتی برنامه‌هایی که هنوز پشتیبانی صریح HDR ندارند، است. Photo Picker با تبدیل کد ویدئوی HDR به فرمت SDR، قصد دارد سازگاری برنامه‌ها را بهبود بخشد و یک تجربه کاربری یکپارچه ارائه دهد.

نحوه‌ی کار ترانس‌کدینگ انتخابگر عکس

قابلیت تبدیل فرمت HDR در Photo Picker به طور پیش‌فرض فعال نیست. برای فعال کردن این ویژگی، برنامه شما باید هنگام اجرای Photo Picker، قابلیت‌های مدیریت فرمت رسانه خود را به صراحت اعلام کند.

برنامه شما قابلیت‌های پردازش رسانه خود را در اختیار انتخابگر عکس قرار می‌دهد. این کار هنگام راه‌اندازی انتخابگر عکس با استفاده از کتابخانه 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 ).

برای غیرفعال کردن کامل تبدیل کد، برای MediaCapabilities null را وارد کنید. هر نوع HDR که به صراحت در قابلیت‌های ارائه شده شما ذکر نشده باشد، پشتیبانی نشده در نظر گرفته خواهد شد. این API در اندروید ۱۳ (سطح API ۳۳) و بالاتر پشتیبانی می‌شود و با @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

  • عملکرد و فضای ذخیره‌سازی: تبدیل کد زمان پردازش زیادی می‌برد و یک فایل جدید ایجاد می‌کند که فضای ذخیره‌سازی را اشغال می‌کند.
  • محدودیت طول ویدیو: برای ایجاد تعادل بین تجربه کاربری و محدودیت‌های فضای ذخیره‌سازی، محدودیت ۱ دقیقه‌ای برای طول ویدیو وجود دارد.
  • مدیریت فایل‌های ذخیره‌شده در حافظه پنهان: فایل‌های کدگذاری‌شده در حافظه پنهان به‌طور دوره‌ای در طول تعمیر و نگهداری غیرفعال پاک می‌شوند تا از استفاده بیش از حد از فضای ذخیره‌سازی جلوگیری شود.
  • در دسترس بودن دستگاه: تبدیل کد عکس توسط انتخابگر عکس در اندروید ۱۳ (سطح API ۳۳) و بالاتر پشتیبانی می‌شود.
  • یکپارچه‌سازی فعالیت AndroidX: مطمئن شوید که از نسخه 1.11.0-alpha01 یا نسخه‌های آلفا/بتا/RC/پایدار بعدی کتابخانه AndroidX Activity استفاده می‌کنید، زیرا این نسخه شامل API لازم setMediaCapabilitiesForTranscoding است.