I am trying to retrieve the icon displayed in a system notification, such as "Do Not Disturb turned on," using NotificationListenerService. The notification comes from the package com.android.systemui.
What I've Tried: Extracting the smallIcon and largeIcon:
// Extract large icon
val largeIcon = notification.getLargeIcon()
// Extract small icon
val smallIcon = notification.smallIcon
largeIcon is null. smallIcon is not null, but it contains a very basic black icon that is different from the actual icon displayed in the notification list. On my phone, the displayed icon is white on a blue background.
Question:
Additional Information:
Any guidance on how to retrieve and display the actual notification icon would be greatly appreciated!
I ended up with creating app icon from small icon, using shape of my own app icon, so it will be default android shape:
fun appIconBitmapFromSmallIcon(smallIcon: Icon): Bitmap {
return try {
// Load the small icon as a Drawable
val smallIconDrawable = smallIcon.loadDrawable(applicationContext)
val smallIconBitmap = smallIconDrawable?.let { getBitmapFromDrawable(it) }
if (smallIconBitmap == null) {
return noImageBitmap
}
// Create a blue background that matches the app icon shape
val size = 256 // Adjust to the desired icon size
val appIconBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
val canvas = Canvas(appIconBitmap)
// Draw the app icon shape on the canvas
val appIconShapeBitmap = getAppIconShapeBitmap(Color.rgb(23, 109, 238), size)
canvas.drawBitmap(appIconShapeBitmap, 0f, 0f, null)
// Convert small icon to white and scale it to fit in the center
val whiteSmallIconBitmap = convertBitmapToWhite(smallIconBitmap)
val overlaySize = size / 2 // Adjust size relative to the background
val scaledSmallIcon = Bitmap.createScaledBitmap(
whiteSmallIconBitmap,
overlaySize,
overlaySize,
true
)
val left = (size - overlaySize) / 2
val top = (size - overlaySize) / 2
// Draw the small icon on top of the blue background
canvas.drawBitmap(scaledSmallIcon, left.toFloat(), top.toFloat(), null)
appIconBitmap
} catch (e: Exception) {
logger.error(e, "Failed to create app icon image")
noImageBitmap
}
}
// Helper method to convert Drawable to Bitmap
private fun getBitmapFromDrawable(
drawable: Drawable,
width: Int? = null,
height: Int? = null
): Bitmap {
val finalWidth = width ?: drawable.intrinsicWidth
val finalHeight = height ?: drawable.intrinsicHeight
if (drawable is BitmapDrawable) {
if (width == null && height == null) {
return drawable.bitmap
} else {
return Bitmap.createScaledBitmap(drawable.bitmap, finalWidth, finalHeight, false)
}
}
val bitmap = Bitmap.createBitmap(finalWidth, finalHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
// Helper method to convert a Bitmap to white
private fun convertBitmapToWhite(bitmap: Bitmap): Bitmap {
val result = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(result)
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
paint.colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, 0f, 0f, paint)
return result
}
// Helper method to get the app icon shape as a Bitmap
private fun getAppIconShapeBitmap(color: Int, size: Int): Bitmap {
// Get the current app icon as a Drawable
val currentAppIconDrawable: Drawable =
applicationContext.packageManager.getApplicationIcon(applicationContext.packageName)
// Convert the Drawable to a Bitmap
val bitmap = getBitmapFromDrawable(currentAppIconDrawable, size, size)
// Create a new Bitmap to paint the icon in white
val whiteBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
val canvas = Canvas(whiteBitmap)
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
// Apply the desired color filter (white in this case)
paint.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
// Draw the original icon onto the canvas with the white paint
canvas.drawBitmap(bitmap, 0f, 0f, paint)
return whiteBitmap
}