-
Notifications
You must be signed in to change notification settings - Fork 669
Description
Feature Request
Plugin
@capacitor/local-notifications
Description
On Android, the largeIcon option currently only supports referencing drawable resource names (e.g. "icon_name"). This makes it hard/impossible to show dynamic images in local notifications when those images are downloaded/user-specific and cached locally on the device (e.g. file://... paths or content://... URIs).
On iOS, similar use cases can be handled via attachments pointing to local file URLs. On Android, there is no equivalent way in the plugin to provide a local file/URI for largeIcon (or an expanded image style), even though the native Android notification API supports setting a bitmap via NotificationCompat.Builder.setLargeIcon(Bitmap).
Related: #430
Platform(s)
Android
Preferred Solution
Add support for providing a local file path / URI for the notification large icon in a backwards-compatible way.
Option A (backwards-compatible, no API change):
Continue accepting largeIcon: string, but interpret it as:
- If
largeIconis a resource name (current behavior), resolve drawable by name. - If
largeIconlooks like a local path/URI:file://...or absolute/...path → decode bitmap from file pathcontent://...→ open stream viaContentResolverand decode bitmap- call
NotificationCompat.Builder.setLargeIcon(bitmap)
Option B (explicit API):
Introduce a new field (e.g. largeIconPath / largeIconUrl) for Android to avoid overloading semantics, while keeping existing largeIcon behavior as-is.
Alternatives
- Pre-bundle images as Android drawables and reference them by name. This only works for static build-time assets and does not work for downloaded/dynamic images.
Additional Context
Native implementation sketch (Android):
val value = largeIconString
val bmp: Bitmap? = when {
value.startsWith("content://") -> context.contentResolver
.openInputStream(Uri.parse(value))
?.use { BitmapFactory.decodeStream(it) }
value.startsWith("file://") -> BitmapFactory.decodeFile(Uri.parse(value).path)
value.startsWith("/") -> BitmapFactory.decodeFile(value)
else -> null
}
if (bmp != null) {
builder.setLargeIcon(bmp)
} else {
// existing behavior: resolve drawable by name
resolveDrawableByName(value)?.let { builder.setLargeIcon(it) }
}Notes:
- Consider downsampling/scaling to avoid large allocations for big images.
content://handling may require appropriate permissions depending on how the URI was obtained.
Related issue: