diff --git a/app/src/main/java/com/example/util/simpletimetracker/notification/NotificationManagerImpl.kt b/app/src/main/java/com/example/util/simpletimetracker/notification/NotificationManagerImpl.kt index 6b31ac8e..d8988128 100644 --- a/app/src/main/java/com/example/util/simpletimetracker/notification/NotificationManagerImpl.kt +++ b/app/src/main/java/com/example/util/simpletimetracker/notification/NotificationManagerImpl.kt @@ -6,9 +6,21 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.content.res.ColorStateList +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.PorterDuff +import android.graphics.PorterDuffColorFilter +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable import android.os.Build +import android.widget.RemoteViews +import androidx.appcompat.content.res.AppCompatResources import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat +import androidx.core.content.ContextCompat +import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat import com.example.util.simpletimetracker.R import com.example.util.simpletimetracker.core.manager.NotificationParams import com.example.util.simpletimetracker.domain.di.AppContext @@ -19,7 +31,8 @@ class NotificationManagerImpl @Inject constructor( @AppContext private val context: Context ) : com.example.util.simpletimetracker.core.manager.NotificationManager { - private val notificationManager: NotificationManagerCompat = NotificationManagerCompat.from(context) + private val notificationManager: NotificationManagerCompat = + NotificationManagerCompat.from(context) override fun show(params: NotificationParams) { val notification: Notification = buildNotification(params) @@ -32,6 +45,18 @@ class NotificationManagerImpl @Inject constructor( } private fun buildNotification(params: NotificationParams): Notification { + val notificationLayout = RemoteViews(context.packageName, R.layout.notification_layout) + notificationLayout.setTextViewText(R.id.tvNotificationName, params.text) + + // TODO add runCatching everywhere + val icon = getVectorDrawable(params.icon) + val iconBackground = ContextCompat.getDrawable(context, R.drawable.circle_drawable) + ?.apply { colorFilter = PorterDuffColorFilter(params.color, PorterDuff.Mode.SRC_IN) } + ?.let { getBitmap(it) } + + notificationLayout.setImageViewBitmap(R.id.ivNotificationIcon, icon) + notificationLayout.setImageViewBitmap(R.id.ivNotificationIconBackground, iconBackground) + val startIntent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP } @@ -42,11 +67,11 @@ class NotificationManagerImpl @Inject constructor( PendingIntent.FLAG_UPDATE_CURRENT ) val builder = NotificationCompat.Builder(context, REMINDERS_CHANNEL_ID) - .setSmallIcon(R.drawable.ic_timer_24px) - .setContentTitle("Simple Time Tracker") - .setContentText(params.text) + .setSmallIcon(R.drawable.ic_notification) .setContentIntent(contentIntent) .setOngoing(true) + .setCustomContentView(notificationLayout) + .setStyle(NotificationCompat.DecoratedCustomViewStyle()) return builder.build() } @@ -61,6 +86,35 @@ class NotificationManagerImpl @Inject constructor( } } + // TODO move to utils and from pie chart? + private fun getVectorDrawable(iconId: Int): Bitmap? { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + (AppCompatResources.getDrawable(context, iconId) as? BitmapDrawable)?.apply { + colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN) + return bitmap + } + } else { + VectorDrawableCompat.create(context.resources, iconId, context.theme)?.apply { + setTintList(ColorStateList.valueOf(Color.WHITE)) + return getBitmap(this) + } + } + + return null + } + + private fun getBitmap(drawable: Drawable): Bitmap { + 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 + } + companion object { private const val REMINDERS_CHANNEL_ID = "REMINDERS" private const val REMINDERS_CHANNEL_NAME = "Notifications" diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml new file mode 100644 index 00000000..e6ad2858 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/notification_layout.xml b/app/src/main/res/layout/notification_layout.xml new file mode 100644 index 00000000..8fbbbd56 --- /dev/null +++ b/app/src/main/res/layout/notification_layout.xml @@ -0,0 +1,41 @@ + + + + + + + + + + \ No newline at end of file diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/NotificationInteractor.kt b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/NotificationInteractor.kt index ea72f0c3..0005bdf8 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/NotificationInteractor.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/NotificationInteractor.kt @@ -1,18 +1,39 @@ package com.example.util.simpletimetracker.core.interactor +import com.example.util.simpletimetracker.core.R import com.example.util.simpletimetracker.core.manager.NotificationManager import com.example.util.simpletimetracker.core.manager.NotificationParams +import com.example.util.simpletimetracker.core.mapper.ColorMapper +import com.example.util.simpletimetracker.core.mapper.IconMapper +import com.example.util.simpletimetracker.core.repo.ResourceRepo import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor import javax.inject.Inject class NotificationInteractor @Inject constructor( private val notificationManager: NotificationManager, - private val recordTypeInteractor: RecordTypeInteractor + private val recordTypeInteractor: RecordTypeInteractor, + private val iconMapper: IconMapper, + private val colorMapper: ColorMapper, + private val resourceRepo: ResourceRepo ) { suspend fun showNotification(typeId: Long) { - val text = recordTypeInteractor.get(typeId)?.name.orEmpty() - notificationManager.show(NotificationParams(typeId.toInt(), text)) + val recordType = recordTypeInteractor.get(typeId) + + notificationManager.show( + NotificationParams( + id = typeId.toInt(), + icon = recordType?.icon + ?.let(iconMapper::mapToDrawableResId) + ?: R.drawable.unknown, + color = recordType?.color + ?.let(colorMapper::mapToColorResId) + ?.let(resourceRepo::getColor) + ?: resourceRepo.getColor(R.color.black), + text = recordType?.name + .orEmpty() + ) + ) } fun hideNotification(typeId: Long) { diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/manager/NotificationParams.kt b/core/src/main/java/com/example/util/simpletimetracker/core/manager/NotificationParams.kt index 54ba081b..738567e5 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/manager/NotificationParams.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/manager/NotificationParams.kt @@ -2,5 +2,7 @@ package com.example.util.simpletimetracker.core.manager data class NotificationParams( val id: Int, + val icon: Int, + val color: Int, val text: String ) \ No newline at end of file diff --git a/core/src/main/res/drawable/circle_drawable.xml b/core/src/main/res/drawable/circle_drawable.xml index 48b0b708..dcd27b47 100644 --- a/core/src/main/res/drawable/circle_drawable.xml +++ b/core/src/main/res/drawable/circle_drawable.xml @@ -2,4 +2,5 @@ + \ No newline at end of file