如何从 Android 中的 StatusBarNotification 中检索系统通知的图标(例如“请勿打扰”)?

问题描述 投票:0回答:1

我正在尝试使用NotificationListenerService检索系统通知中显示的图标,例如“请勿打扰已打开”。该通知来自 com.android.systemui 包。

我尝试过的: 提取小图标和大图标:

// Extract large icon
val largeIcon = notification.getLargeIcon()

// Extract small icon
val smallIcon = notification.smallIcon

largeIcon 为空。 SmallIcon 不为 null,但它包含一个非常基本的黑色图标,与通知列表中显示的实际图标不同。在我的手机上,显示的图标是蓝底白字。

问题:

  1. StatusBarNotification 或Notification 对象中的哪个字段包含系统通知列表中显示的图标(蓝底白字表示“请勿打扰”)?
  2. 如何检索此图标并将其转换为可绘制、位图或图标?

附加信息:

  1. 通知的包名为“com.android.systemui”。
  2. com.android.systemui 包的图标与“请勿打扰”通知图标不同。
  3. 我的应用程序具有NotificationListenerService和UsageStats的权限。

任何有关如何检索和显示实际通知图标的指导将不胜感激!

java android kotlin notifications icons
1个回答
0
投票

我最终使用我自己的应用程序图标的形状从小图标创建应用程序图标,因此它将是默认的 Android 形状:

    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
    }
© www.soinside.com 2019 - 2024. All rights reserved.