mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-08-14 13:51:57 +00:00
Update: Pack all notify functions in NotificationUtils
This commit is contained in:
286
src/main/kotlin/com/looker/droidify/utility/NotificationUtils.kt
Normal file
286
src/main/kotlin/com/looker/droidify/utility/NotificationUtils.kt
Normal file
@@ -0,0 +1,286 @@
|
||||
package com.looker.droidify.utility
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.ContextThemeWrapper
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.looker.droidify.NOTIFICATION_CHANNEL_DOWNLOADING
|
||||
import com.looker.droidify.NOTIFICATION_CHANNEL_INSTALLER
|
||||
import com.looker.droidify.NOTIFICATION_CHANNEL_SYNCING
|
||||
import com.looker.droidify.NOTIFICATION_CHANNEL_UPDATES
|
||||
import com.looker.droidify.NOTIFICATION_ID_DOWNLOADING
|
||||
import com.looker.droidify.NOTIFICATION_ID_INSTALLER
|
||||
import com.looker.droidify.NOTIFICATION_ID_SYNCING
|
||||
import com.looker.droidify.NOTIFICATION_ID_UPDATES
|
||||
import com.looker.droidify.R
|
||||
import com.looker.droidify.database.entity.Repository
|
||||
import com.looker.droidify.entity.ProductItem
|
||||
import com.looker.droidify.index.RepositoryUpdater
|
||||
import com.looker.droidify.installer.InstallerService
|
||||
import com.looker.droidify.service.DownloadService
|
||||
import com.looker.droidify.ui.activities.MainActivityX
|
||||
import com.looker.droidify.utility.extension.android.Android
|
||||
import com.looker.droidify.utility.extension.android.notificationManager
|
||||
import com.looker.droidify.utility.extension.resources.getColorFromAttr
|
||||
|
||||
/**
|
||||
* Displays summary of available updates.
|
||||
*
|
||||
* @param productItems list of apps pending updates
|
||||
*/
|
||||
fun Context.displayUpdatesNotification(productItems: List<ProductItem>) {
|
||||
val maxUpdates = 5
|
||||
fun <T> T.applyHack(callback: T.() -> Unit): T = apply(callback)
|
||||
notificationManager.notify(
|
||||
NOTIFICATION_ID_UPDATES, NotificationCompat
|
||||
.Builder(this, NOTIFICATION_CHANNEL_UPDATES)
|
||||
.setSmallIcon(R.drawable.ic_new_releases)
|
||||
.setContentTitle(getString(R.string.new_updates_available))
|
||||
.setContentText(
|
||||
resources.getQuantityString(
|
||||
R.plurals.new_updates_DESC_FORMAT,
|
||||
productItems.size, productItems.size
|
||||
)
|
||||
)
|
||||
.setColor(
|
||||
ContextThemeWrapper(this, R.style.Theme_Main_Light)
|
||||
.getColorFromAttr(android.R.attr.colorPrimary).defaultColor
|
||||
)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
Intent(this, MainActivityX::class.java)
|
||||
.setAction(MainActivityX.ACTION_UPDATES)
|
||||
.putExtra(
|
||||
MainActivityX.EXTRA_UPDATES,
|
||||
productItems.map { it.packageName }.toTypedArray()
|
||||
),
|
||||
if (Android.sdk(23))
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
else
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
)
|
||||
.setStyle(NotificationCompat.InboxStyle().applyHack {
|
||||
for (productItem in productItems.take(maxUpdates)) {
|
||||
val builder = SpannableStringBuilder(productItem.name)
|
||||
builder.setSpan(
|
||||
ForegroundColorSpan(Color.BLACK), 0, builder.length,
|
||||
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
builder.append(' ').append(productItem.version)
|
||||
addLine(builder)
|
||||
}
|
||||
if (productItems.size > maxUpdates) {
|
||||
val summary =
|
||||
getString(R.string.plus_more_FORMAT, productItems.size - maxUpdates)
|
||||
if (Android.sdk(24)) {
|
||||
addLine(summary)
|
||||
} else {
|
||||
setSummaryText(summary)
|
||||
}
|
||||
}
|
||||
})
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
fun Context.showNotificationError(repository: Repository, exception: Exception) {
|
||||
notificationManager.notify(
|
||||
"repository-${repository.id}", NOTIFICATION_ID_SYNCING, NotificationCompat
|
||||
.Builder(this, NOTIFICATION_CHANNEL_SYNCING)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_warning)
|
||||
.setColor(
|
||||
ContextThemeWrapper(this, R.style.Theme_Main_Light)
|
||||
.getColorFromAttr(android.R.attr.colorPrimary).defaultColor
|
||||
)
|
||||
.setContentTitle(getString(R.string.could_not_sync_FORMAT, repository.name))
|
||||
.setContentText(
|
||||
getString(
|
||||
when (exception) {
|
||||
is RepositoryUpdater.UpdateException -> when (exception.errorType) {
|
||||
RepositoryUpdater.ErrorType.NETWORK -> R.string.network_error_DESC
|
||||
RepositoryUpdater.ErrorType.HTTP -> R.string.http_error_DESC
|
||||
RepositoryUpdater.ErrorType.VALIDATION -> R.string.validation_index_error_DESC
|
||||
RepositoryUpdater.ErrorType.PARSING -> R.string.parsing_index_error_DESC
|
||||
}
|
||||
else -> R.string.unknown_error_DESC
|
||||
}
|
||||
)
|
||||
)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
fun Context.showNotificationError(
|
||||
task: DownloadService.Task,
|
||||
errorType: DownloadService.ErrorType
|
||||
) {
|
||||
notificationManager.notify(task.notificationTag,
|
||||
NOTIFICATION_ID_DOWNLOADING,
|
||||
NotificationCompat
|
||||
.Builder(this, NOTIFICATION_CHANNEL_DOWNLOADING)
|
||||
.setAutoCancel(true)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_warning)
|
||||
.setColor(
|
||||
ContextThemeWrapper(this, R.style.Theme_Main_Light)
|
||||
.getColorFromAttr(R.attr.colorPrimary).defaultColor
|
||||
)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
Intent(this, MainActivityX::class.java)
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.setData(Uri.parse("package:${task.packageName}"))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
|
||||
if (Android.sdk(23))
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
else
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
)
|
||||
.apply {
|
||||
when (errorType) {
|
||||
is DownloadService.ErrorType.Network -> {
|
||||
setContentTitle(
|
||||
getString(
|
||||
R.string.could_not_download_FORMAT,
|
||||
task.name
|
||||
)
|
||||
)
|
||||
setContentText(getString(R.string.network_error_DESC))
|
||||
}
|
||||
is DownloadService.ErrorType.Http -> {
|
||||
setContentTitle(
|
||||
getString(
|
||||
R.string.could_not_download_FORMAT,
|
||||
task.name
|
||||
)
|
||||
)
|
||||
setContentText(getString(R.string.http_error_DESC))
|
||||
}
|
||||
is DownloadService.ErrorType.Validation -> {
|
||||
setContentTitle(
|
||||
getString(
|
||||
R.string.could_not_validate_FORMAT,
|
||||
task.name
|
||||
)
|
||||
)
|
||||
setContentText(
|
||||
getString(
|
||||
when (errorType.validateError) {
|
||||
DownloadService.ValidationError.INTEGRITY -> R.string.integrity_check_error_DESC
|
||||
DownloadService.ValidationError.FORMAT -> R.string.file_format_error_DESC
|
||||
DownloadService.ValidationError.METADATA -> R.string.invalid_metadata_error_DESC
|
||||
DownloadService.ValidationError.SIGNATURE -> R.string.invalid_signature_error_DESC
|
||||
DownloadService.ValidationError.PERMISSIONS -> R.string.invalid_permissions_error_DESC
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}::class
|
||||
}
|
||||
.build())
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies user of installer outcome. This can be success, error, or a request for user action
|
||||
* if installation cannot proceed automatically.
|
||||
*
|
||||
* @param intent provided by PackageInstaller to the callback service/activity.
|
||||
*/
|
||||
fun InstallerService.notifyStatus(intent: Intent?) {
|
||||
// unpack from intent
|
||||
val status = intent?.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)
|
||||
val sessionId = intent?.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1) ?: 0
|
||||
|
||||
// get package information from session
|
||||
val sessionInstaller = this.packageManager.packageInstaller
|
||||
val session = if (sessionId > 0) sessionInstaller.getSessionInfo(sessionId) else null
|
||||
|
||||
val name =
|
||||
session?.appPackageName ?: intent?.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
|
||||
val message = intent?.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
||||
val installerAction = intent?.getStringExtra(InstallerService.KEY_ACTION)
|
||||
|
||||
// get application name for notifications
|
||||
val appLabel = session?.appLabel ?: intent?.getStringExtra(InstallerService.KEY_APP_NAME)
|
||||
?: try {
|
||||
if (name != null) packageManager.getApplicationLabel(
|
||||
packageManager.getApplicationInfo(
|
||||
name,
|
||||
PackageManager.GET_META_DATA
|
||||
)
|
||||
) else null
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
val notificationTag = "${InstallerService.NOTIFICATION_TAG_PREFIX}$name"
|
||||
|
||||
// start building
|
||||
val builder = NotificationCompat
|
||||
.Builder(this, NOTIFICATION_CHANNEL_INSTALLER)
|
||||
.setAutoCancel(true)
|
||||
.setColor(
|
||||
ContextThemeWrapper(this, R.style.Theme_Main_Light)
|
||||
.getColorFromAttr(R.attr.colorPrimary).defaultColor
|
||||
)
|
||||
|
||||
when (status) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
// request user action with "downloaded" notification that triggers a working prompt
|
||||
notificationManager.notify(
|
||||
notificationTag, NOTIFICATION_ID_INSTALLER, builder
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
.setContentIntent(installIntent(intent))
|
||||
.setContentTitle(getString(R.string.downloaded_FORMAT, appLabel))
|
||||
.setContentText(getString(R.string.tap_to_install_DESC))
|
||||
.build()
|
||||
)
|
||||
}
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
if (installerAction == InstallerService.ACTION_UNINSTALL)
|
||||
// remove any notification for this app
|
||||
notificationManager.cancel(notificationTag, NOTIFICATION_ID_INSTALLER)
|
||||
else {
|
||||
val notification = builder
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
.setContentTitle(getString(R.string.installed))
|
||||
.setContentText(appLabel)
|
||||
.setTimeoutAfter(InstallerService.INSTALLED_NOTIFICATION_TIMEOUT)
|
||||
.build()
|
||||
notificationManager.notify(
|
||||
notificationTag,
|
||||
NOTIFICATION_ID_INSTALLER,
|
||||
notification
|
||||
)
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED -> {
|
||||
// do nothing if user cancels
|
||||
}
|
||||
else -> {
|
||||
// problem occurred when installing/uninstalling package
|
||||
val notification = builder
|
||||
.setSmallIcon(android.R.drawable.stat_notify_error)
|
||||
.setContentTitle(getString(R.string.unknown_error_DESC))
|
||||
.setContentText(message)
|
||||
.build()
|
||||
notificationManager.notify(
|
||||
notificationTag,
|
||||
NOTIFICATION_ID_INSTALLER,
|
||||
notification
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user