Reputation:
I am trying to get the icon of an application's notification. The listener works perfectly, but for most of the apps I tried (telegram, signal, android messages...) I cannot seem to get the app's icon.
Here is the code where I try to get the icon:
private fun getIcon(notification: StatusBarNotification, context: Context): Bitmap {
val packageManager = context.packageManager
return try {
Bitmap.createBitmap(drawableToBitmap(packageManager.getApplicationIcon(notification.packageName)))
} catch (exception: PackageManager.NameNotFoundException) {
return Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8)
}
}
private fun drawableToBitmap(drawable: Drawable): Bitmap {
if (drawable is BitmapDrawable) {
if (drawable.bitmap != null) {
return drawable.bitmap
}
}
val bitmap: Bitmap = if (drawable.intrinsicWidth <= 0 || drawable.intrinsicHeight <= 0) {
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
} else {
Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
}
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
Upvotes: 0
Views: 681
Reputation: 1324
To get the icons you should use both class & package names instead of only using the package name. If the app supports changing icons or has more than one launcher activity this works much better.
fun getIcon(context: Context, packageName: String, className: String): Drawable? {
var drawable: Drawable? = null
try {
val intent = Intent(Intent.ACTION_MAIN)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.setClassName(packageName, className)
drawable = context.packageManager.getActivityIcon(intent)
} catch (e: Exception) {
try {
drawable = context.packageManager.getApplicationIcon(packageName)
} catch (e: Exception) {
e.printStackTrace()
}
}
return drawable
}
This function returns the icon drawable or returns null if it fails. It tries to get the icon using both package and class names at first but if it fails it uses only package name. You can just use the package name one if you don't want to use the class name as well.
If it's still just catching the exception every time and you know the app is installed, you probably lack some permissions. You can also try again with targetSdkVersion 29
instead of targetSdkVersion 30
since 30 adds some limitations to this kind of functions but I am not sure if those affect getting the icons as well.
Upvotes: 0