Manage assets in Android local asset sources by updating metadata, removing individual assets, or deleting entire sources.
Assets in local sources can change after users import or generate media. CE.SDK lets you query those assets, replace their metadata by removing and re-adding them, remove stale entries, and notify subscribers when a source changes.
This guide assumes your app already owns a populated local asset source. For the source setup pattern, see Import Local Asset. Creating upload UI and remote source backends are separate topics.
Finding Assets in a Source#
Use engine.asset.findAssets() before editing or removing an item. Android query pages are zero-based, and locale controls which localized labels and tags are searched.
val queryResult = engine.asset.findAssets( sourceId = sourceId, query = FindAssetsQuery( page = 0, perPage = 100, query = "logo", locale = "en", ),)val assetToEdit = queryResult.assets.firstOrNull { asset -> asset.id == "brand-logo" } ?: error("Expected brand-logo in $sourceId.")The returned FindAssetsResult includes the matching assets, the total count, the requested currentPage, and nextPage when another page is available.
Updating Asset Metadata#
Android local sources do not expose a direct update method. Remove the existing asset, then add an updated AssetDefinition with the same ID.
val updatedLogoAsset = logoAsset.copy( label = mapOf("en" to "Primary Brand Logo"), tags = mapOf("en" to listOf("logo", "brand", "primary")),)
engine.asset.removeAsset(sourceId = sourceId, assetId = assetToEdit.id)engine.asset.addAsset(sourceId = sourceId, asset = updatedLogoAsset)Reusing the ID keeps your app-level references stable while changing the label, tags, URI, thumbnail, or other metadata stored in the source.
Removing an Asset From a Source#
Remove a single entry with engine.asset.removeAsset(). This deletes the asset from the source catalog, but it does not delete blocks that were already created from that asset.
engine.asset.removeAsset( sourceId = sourceId, assetId = "campaign-background",)Use this for user-driven deletion, cleanup of temporary imports, or removing outdated generated assets from a local collection.
Notifying After Out-of-Band Changes#
Calls to engine.asset.addAsset() and engine.asset.removeAsset() already notify source subscribers. Call engine.asset.assetSourceContentsChanged() only after your app changes source backing data outside the local asset API, so asset-library UI and other subscribers know to re-query the source.
// Use this after changing backing data outside addAsset/removeAsset.engine.asset.assetSourceContentsChanged(sourceId = temporarySourceId)When you change several backing files or metadata records outside CE.SDK, call it once after the batch instead of once per item.
Removing an Entire Asset Source#
Remove a complete source with engine.asset.removeSource(). This removes the source registration and all assets stored in that local source.
engine.asset.removeSource(sourceId = temporarySourceId)Use this when a temporary session ends or when your app deletes an entire user-managed asset category. If you need to create and populate local sources first, follow the source setup in Import Local Asset.
Listening to Asset Source Events#
The asset API exposes Flow<String> streams for source additions, removals, and content updates. Collect these flows in the lifecycle scope that owns your asset library UI or background workflow, then cancel the returned Job when that owner is disposed.
return engine.asset.onAssetSourceUpdated() .onEach { updatedSourceId -> if (updatedSourceId == sourceId) { Log.i(TAG, "Asset source updated: $updatedSourceId") } } .launchIn(assetSourceLifecycleScope)Use the same pattern with onAssetSourceAdded() or onAssetSourceRemoved() when you need to react to source registration or cleanup events.
Best Practices#
- Query before mutating: Use
findAssets()to verify the asset ID before removing or replacing it. - Notify only for out-of-band changes:
addAsset()andremoveAsset()already notify subscribers; reserveassetSourceContentsChanged()for backing data changes made outside those APIs. - Scope event subscriptions: Collect source event flows in the owning lifecycle scope and cancel the job when that owner is disposed.
- Use source-specific IDs: Keep persistent, temporary, and generated sources clearly separated.
Troubleshooting#
| Issue | Cause | Solution |
|---|---|---|
| Asset not found | The ID, query, locale, tags, or groups do not match the source contents | Query the source with a wider FindAssetsQuery before mutating |
| Source updates are not visible | Subscribers have not been notified after an external or batched backing-data change | Call assetSourceContentsChanged(sourceId=_) after the external mutation completes |
| Cannot remove assets | The source is not a local source or the custom source does not implement removal support | Manage assets through a local source or implement removal behavior on the custom AssetSource |
| Source remains available | Cleanup only removed individual assets | Call removeSource(sourceId=_) when the whole catalog should disappear |
API Reference#
| Method | Description |
|---|---|
engine.asset.addAsset(sourceId=_, asset=_) |
Re-add an updated AssetDefinition to a local source |
engine.asset.findAssets(sourceId=_, query=_) |
Query assets from a source with paging, search, locale, tags, and groups |
engine.asset.removeAsset(sourceId=_, assetId=_) |
Remove one asset from a local source |
engine.asset.assetSourceContentsChanged(sourceId=_) |
Notify subscribers after backing data changes outside local asset API calls |
engine.asset.removeSource(sourceId=_) |
Remove an entire asset source and its local assets |
engine.asset.onAssetSourceAdded() |
Observe source registration events |
engine.asset.onAssetSourceUpdated() |
Observe source content update events |
engine.asset.onAssetSourceRemoved() |
Observe source removal events |
Next Steps#
- Import Local Asset - Import files directly from the user’s device and insert them into the design canvas.
- Customize - Adapt the asset library UI and behavior to suit your application’s structure and user needs.