The Android editor provides an optional asset source that indexes the device gallery (images and videos) via the Android MediaStore. This section explains how to opt in, how the default (upload-only) workflow behaves, and how to take care of the required permissions when the gallery integration is enabled.
Default behavior#
- By default, the SDK keeps the system gallery disabled and relies on the upload buttons and camera intents. The Gallery section stays visible but starts empty and fills with the media that users add or capture while editing. This means no storage permissions are requested automatically and the media picker is handled by system intents.
- Opt in by calling
SystemGalleryPermission.setModeinside yourEngineConfiguration.onCreatecallback (or any later editor scope). This keeps the opt-in explicit even when you rely on the helper composables. - Once enabled, the asset library shows a Gallery section and the dock/timeline expose a Gallery quick action (
Dock.Button.rememberSystemGallery). When end users only grant partial access (Android 13+ “selected photos”), the UI combines the selected items with the MediaStore listing.
import ly.img.editor.EngineConfigurationimport ly.img.editor.EditorDefaultsimport ly.img.editor.core.library.data.SystemGalleryConfigurationimport ly.img.editor.core.library.data.SystemGalleryPermission
@Composablefun rememberEngineConfiguration(license: String): EngineConfiguration = EngineConfiguration.remember( license = license, onCreate = { EditorDefaults.onCreate( editorContext.engine, EngineConfiguration.defaultDesignSceneUri, editorContext.eventHandler, ) SystemGalleryPermission.setMode(SystemGalleryConfiguration.Enabled) }, )If you override the default onCreate handler or build your own engine bootstrap, add the sources manually as shown below.
Adding the system gallery sources manually#
import ly.img.editor.core.library.data.SystemGalleryConfigurationimport ly.img.editor.core.library.data.SystemGalleryPermission
suspend fun onCreate(engine: Engine) { engine.addDefaultAssetSources() SystemGalleryPermission.setMode(SystemGalleryConfiguration.Enabled) // …register any additional asset sources that you need afterwards}If you delegate to EditorDefaults.onCreate, call the scope helper afterwards:
import ly.img.editor.EditorDefaultsimport ly.img.editor.core.library.data.SystemGalleryConfiguration
EditorDefaults.onCreate( engine = engine, sceneUri = sceneUri, eventHandler = eventHandler,)SystemGalleryPermission.setMode(SystemGalleryConfiguration.Enabled)SystemGalleryPermission.setMode updates the gallery permission mode; EditorDefaults wire the sources automatically. If you build the engine manually, add the sources as shown above. The in-editor gallery relies on three sources:
AssetSourceType.GalleryAllVisuals– combined images and videos (used for the default Gallery section)AssetSourceType.GalleryImageAssetSourceType.GalleryVideo
They are exposed in LibraryCategory.getElements and can also be consumed directly from custom LibraryContent definitions. When SystemGalleryConfiguration.Disabled is used, the sources only list the URIs that were manually added during the current session.
Permissions and manifest setup#
-
Declare the following permissions in your app manifest so the runtime requests can be triggered:
READ_MEDIA_IMAGESandREAD_MEDIA_VIDEOon Android 13+READ_MEDIA_VISUAL_USER_SELECTEDon Android 14+ (to support the selected photos mode)- Fallback to
READ_EXTERNAL_STORAGEon Android 12 and lower
-
The built-in UI components (
LibrarySectionHeader,SystemGalleryAddMenu,Dock.Button.rememberSystemGallery) request the appropriate permissions viaActivityResultContracts.RequestMultiplePermissionsand updateGalleryPermissionManagerautomatically. -
If you build your own UI layer, use
GalleryPermissionManager.requiredPermission(mimeType)to obtain the permission set and callGalleryPermissionManager.setSelected(uris, context)when the user picks a limited set of media.
Once the permissions are granted, SystemGalleryAssetSource paginates over MediaStore and refreshes the gallery section automatically.
Legacy upload flow#
The UploadsOnlyAssetLibraryEditorSolution sample demonstrates how to replace the default gallery sections with the classic uploads picker and how to adjust the timeline options accordingly.
val uploadsOnlyImages = remember { LibraryCategory.Images.copy( content = LibraryContent.Sections( titleRes = ly.img.editor.core.R.string.ly_img_editor_asset_library_title_images, sections = listOf( LibraryContent.Section( titleRes = ly.img.editor.core.R.string.ly_img_editor_asset_library_section_image_uploads, sourceTypes = listOf(AssetSourceType.ImageUploads), assetType = AssetType.Image, expandContent = LibraryContent.Grid( titleRes = ly.img.editor.core.R.string.ly_img_editor_asset_library_section_image_uploads, sourceType = AssetSourceType.ImageUploads, assetType = AssetType.Image, ), ), ), ), )}val assetLibrary = remember { AssetLibrary.getDefault(images = uploadsOnlyImages)}If you also want to hide the gallery quick action from the timeline menu, update the global configuration:
Optional:
TimelineConfigurationlives in theeditor-basemodule. You can only adjust it if your app includes is.
import ly.img.editor.base.timeline.state.AddClipOptionimport ly.img.editor.base.timeline.state.TimelineConfiguration
TimelineConfiguration.addClipOptions = listOf(AddClipOption.Camera, AddClipOption.Library)- Update other categories (for example the combined
LibraryCategory.getElements) the same way if you need to hide gallery sections globally. - The stock dock and timeline buttons open the image category, so once that category only contains
AssetSourceType.ImageUploads, the uploads picker shows up automatically.