From 2c3b73ae88d86bcb6e1cfd6986dd009cb89e051b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 5 Feb 2021 09:31:25 +0800 Subject: [PATCH] fix(?) for cyanogen problem with custom statusbar icons --- .../geeksville/mesh/service/MeshService.kt | 3 ++ .../mesh/service/MeshServiceNotifications.kt | 46 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 5090fe03f..b8a4ff2f4 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -344,6 +344,9 @@ class MeshService : Service(), Logging { radio.close() saveSettings() + stopForeground(true) // Make sure we aren't using the notification first + serviceNotifications.close() + super.onDestroy() serviceJob.cancel() } diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt index 207ea93a1..1217c4699 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt @@ -6,27 +6,40 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas import android.graphics.Color import android.os.Build import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.DrawableCompat import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MainActivity import com.geeksville.mesh.R import com.geeksville.mesh.android.notificationManager import com.geeksville.mesh.utf8 +import java.io.Closeable + class MeshServiceNotifications( private val context: Context -) { +) : Closeable +{ private val notificationManager: NotificationManager get() = context.notificationManager val notifyId = 101 + private var largeIcon: Bitmap? = null @RequiresApi(Build.VERSION_CODES.O) private fun createNotificationChannel(): String { val channelId = "my_service" val channelName = context.getString(R.string.meshtastic_service_notifications) - val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH).apply { + val channel = NotificationChannel( + channelId, + channelName, + NotificationManager.IMPORTANCE_HIGH + ).apply { lightColor = Color.BLUE importance = NotificationManager.IMPORTANCE_NONE lockscreenVisibility = Notification.VISIBILITY_PRIVATE @@ -61,6 +74,25 @@ class MeshServiceNotifications( PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), 0) } + /** + * Generate a bitmap from a vector drawable (even on old builds) + * https://stackoverflow.com/questions/33696488/getting-bitmap-from-vector-drawable + */ + fun getBitmapFromVectorDrawable(drawableId: Int): Bitmap { + var drawable = ContextCompat.getDrawable(context, drawableId)!! + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + drawable = DrawableCompat.wrap(drawable).mutate() + } + val bitmap = 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 + } + /** * Generate a new version of our notification - reflecting current app state */ @@ -69,11 +101,16 @@ class MeshServiceNotifications( summaryString: String, senderName: String ): Notification { + // We delay making this bitmap until we know we need it + if(largeIcon == null) + largeIcon = getBitmapFromVectorDrawable(R.mipmap.ic_launcher2) + val category = if (recentReceivedText != null) Notification.CATEGORY_SERVICE else Notification.CATEGORY_MESSAGE val builder = NotificationCompat.Builder(context, channelId).setOngoing(true) .setPriority(NotificationCompat.PRIORITY_MIN) .setCategory(category) .setSmallIcon(if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) R.drawable.app_icon_novect else R.drawable.app_icon) // vector form icons don't work reliably on older androids + .setLargeIcon(largeIcon) // we must include a large icon because of a bug in cyanogenmod https://github.com/open-keychain/open-keychain/issues/1356#issue-89493995 .setContentTitle(summaryString) // leave this off for now so our notification looks smaller .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setContentIntent(openAppIntent) @@ -93,4 +130,9 @@ class MeshServiceNotifications( return builder.build() } + + override fun close() { + largeIcon?.recycle() + largeIcon = null + } }