DownloadWorker: Create and use scaled bitmap for notification icon

Old android versions get binder transaction errors otherwise. Also move out the
logic to fetch icon into the Worker to avoid fetching it 100 times. Keep the install
logic in place as that method is only called once after installation.

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-12-29 19:13:04 +05:30
parent 4d4429fd7a
commit bc252fae1f
2 changed files with 15 additions and 14 deletions

View File

@@ -4,6 +4,8 @@ import android.app.NotificationManager
import android.app.Service import android.app.Service
import android.content.Context import android.content.Context
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log import android.util.Log
import androidx.hilt.work.HiltWorker import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
@@ -49,10 +51,11 @@ class DownloadWorker @AssistedInject constructor(
private lateinit var download: Download private lateinit var download: Download
private lateinit var notificationManager: NotificationManager private lateinit var notificationManager: NotificationManager
private var downloading = false private lateinit var icon: Bitmap
private val NOTIFICATION_ID = 200 private val NOTIFICATION_ID = 200
private var downloading = false
private var totalBytes by Delegates.notNull<Long>() private var totalBytes by Delegates.notNull<Long>()
private var totalProgress = 0 private var totalProgress = 0
private var downloadedBytes = 0L private var downloadedBytes = 0L
@@ -64,6 +67,9 @@ class DownloadWorker @AssistedInject constructor(
try { try {
val downloadData = inputData.getString(DownloadWorkerUtil.DOWNLOAD_DATA) val downloadData = inputData.getString(DownloadWorkerUtil.DOWNLOAD_DATA)
download = gson.fromJson(downloadData, Download::class.java) download = gson.fromJson(downloadData, Download::class.java)
val bitmap = BitmapFactory.decodeStream(URL(download.iconURL).openStream())
icon = Bitmap.createScaledBitmap(bitmap, 96, 96, true)
} catch (exception: Exception) { } catch (exception: Exception) {
Log.e(TAG, "Failed to parse download data", exception) Log.e(TAG, "Failed to parse download data", exception)
return Result.failure() return Result.failure()
@@ -267,7 +273,7 @@ class DownloadWorker @AssistedInject constructor(
override suspend fun getForegroundInfo(): ForegroundInfo { override suspend fun getForegroundInfo(): ForegroundInfo {
val notification = if (this::download.isInitialized) { val notification = if (this::download.isInitialized) {
NotificationUtil.getDownloadNotification(appContext, download, id) NotificationUtil.getDownloadNotification(appContext, download, id, icon)
} else { } else {
NotificationUtil.getDownloadNotification(appContext) NotificationUtil.getDownloadNotification(appContext)
} }
@@ -288,7 +294,7 @@ class DownloadWorker @AssistedInject constructor(
downloadDao.update(download) downloadDao.update(download)
} }
val notification = NotificationUtil.getDownloadNotification(appContext, download, id) val notification = NotificationUtil.getDownloadNotification(appContext, download, id, icon)
val notificationID = if (dID != -1) dID else download.packageName.hashCode() val notificationID = if (dID != -1) dID else download.packageName.hashCode()
notificationManager.notify(notificationID, notification) notificationManager.notify(notificationID, notification)
} }

View File

@@ -7,6 +7,7 @@ import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Color import android.graphics.Color
import android.os.Build import android.os.Build
@@ -86,20 +87,14 @@ object NotificationUtil {
fun getDownloadNotification( fun getDownloadNotification(
context: Context, context: Context,
download: AuroraDownload, download: AuroraDownload,
workID: UUID workID: UUID,
largeIcon: Bitmap? = null
): Notification { ): Notification {
val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_GENERAL) val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_GENERAL)
builder.setContentTitle(download.displayName) builder.setContentTitle(download.displayName)
builder.color = ContextCompat.getColor(context, R.color.colorAccent) builder.color = ContextCompat.getColor(context, R.color.colorAccent)
builder.setContentIntent(getContentIntentForDownloads(context)) builder.setContentIntent(getContentIntentForDownloads(context))
builder.setLargeIcon(largeIcon)
// Set big icon for download
try {
val bitmap = BitmapFactory.decodeStream(URL(download.iconURL).openStream())
builder.setLargeIcon(bitmap)
} catch (exception: Exception) {
Log.i(TAG, "Failed to set big icon", exception)
}
when (download.status) { when (download.status) {
DownloadStatus.CANCELLED -> { DownloadStatus.CANCELLED -> {
@@ -166,10 +161,10 @@ object NotificationUtil {
fun getInstallNotification(context: Context, download: AuroraDownload): Notification { fun getInstallNotification(context: Context, download: AuroraDownload): Notification {
val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT) val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT)
// Set big icon for download // Set scaled big icon for download
try { try {
val bitmap = BitmapFactory.decodeStream(URL(download.iconURL).openStream()) val bitmap = BitmapFactory.decodeStream(URL(download.iconURL).openStream())
builder.setLargeIcon(bitmap) builder.setLargeIcon(Bitmap.createScaledBitmap(bitmap, 96, 96, true))
} catch (exception: Exception) { } catch (exception: Exception) {
Log.i(TAG, "Failed to set big icon", exception) Log.i(TAG, "Failed to set big icon", exception)
} }