InstallReceiver: Notify package installation status as well
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -134,6 +134,7 @@ dependencies {
|
|||||||
implementation("androidx.lifecycle:lifecycle-service:$lifeVersion")
|
implementation("androidx.lifecycle:lifecycle-service:$lifeVersion")
|
||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifeVersion")
|
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifeVersion")
|
||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifeVersion")
|
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifeVersion")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-process:$lifeVersion")
|
||||||
|
|
||||||
//Arch Navigation
|
//Arch Navigation
|
||||||
val navVersion = "2.7.5"
|
val navVersion = "2.7.5"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.net.Uri
|
|||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import com.aurora.extensions.isSAndAbove
|
import com.aurora.extensions.isSAndAbove
|
||||||
import com.aurora.store.BuildConfig
|
import com.aurora.store.BuildConfig
|
||||||
|
import com.aurora.store.data.receiver.InstallReceiver
|
||||||
import com.aurora.store.util.Log
|
import com.aurora.store.util.Log
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -61,12 +62,17 @@ abstract class SessionInstallerBase(context: Context) : InstallerBase(context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val callBackIntent = Intent(context, InstallerService::class.java)
|
val callBackIntent = Intent(context, InstallReceiver::class.java).apply {
|
||||||
|
action = InstallReceiver.ACTION_INSTALL_STATUS
|
||||||
|
setPackage(context.packageName)
|
||||||
|
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName)
|
||||||
|
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||||
|
}
|
||||||
val flags = if (isSAndAbove())
|
val flags = if (isSAndAbove())
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE else
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE else
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
|
||||||
val pendingIntent = PendingIntent.getService(
|
val pendingIntent = PendingIntent.getBroadcast(
|
||||||
context,
|
context,
|
||||||
sessionId,
|
sessionId,
|
||||||
callBackIntent,
|
callBackIntent,
|
||||||
|
|||||||
@@ -18,35 +18,148 @@
|
|||||||
*/
|
*/
|
||||||
package com.aurora.store.data.receiver
|
package com.aurora.store.data.receiver
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageInstaller
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.core.content.IntentCompat
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
import com.aurora.Constants
|
import com.aurora.Constants
|
||||||
|
import com.aurora.gplayapi.data.models.App
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.data.event.InstallerEvent
|
||||||
import com.aurora.store.data.installer.AppInstaller
|
import com.aurora.store.data.installer.AppInstaller
|
||||||
|
import com.aurora.store.util.NotificationUtil
|
||||||
import com.aurora.store.util.PathUtil
|
import com.aurora.store.util.PathUtil
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
class InstallReceiver : BroadcastReceiver() {
|
class InstallReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ACTION_INSTALL_APP = "com.aurora.store.data.receiver.InstallReceiver.INSTALL_APP"
|
||||||
|
const val ACTION_INSTALL_STATUS =
|
||||||
|
"com.aurora.store.data.receiver.InstallReceiver.INSTALL_STATUS"
|
||||||
|
}
|
||||||
|
|
||||||
private val TAG = InstallReceiver::class.java.simpleName
|
private val TAG = InstallReceiver::class.java.simpleName
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val packageName = intent.extras?.getString(Constants.STRING_APP) ?: String()
|
when (intent.action) {
|
||||||
val version = intent.extras?.getInt(Constants.STRING_VERSION)
|
ACTION_INSTALL_APP -> {
|
||||||
if (packageName.isNotBlank() && version != null) {
|
val packageName = intent.extras?.getString(Constants.STRING_APP) ?: String()
|
||||||
try {
|
val version = intent.extras?.getInt(Constants.STRING_VERSION)
|
||||||
val downloadDir =
|
if (packageName.isNotBlank() && version != null) {
|
||||||
File(PathUtil.getAppDownloadDir(context, packageName, version).pathString)
|
try {
|
||||||
AppInstaller.getInstance(context).getPreferredInstaller()
|
val downloadDir =
|
||||||
.install(
|
File(
|
||||||
packageName,
|
PathUtil.getAppDownloadDir(
|
||||||
downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") }
|
context,
|
||||||
)
|
packageName,
|
||||||
} catch (exception: Exception) {
|
version
|
||||||
Log.e(TAG, "Failed to install $packageName")
|
).pathString
|
||||||
|
)
|
||||||
|
AppInstaller.getInstance(context).getPreferredInstaller()
|
||||||
|
.install(
|
||||||
|
packageName,
|
||||||
|
downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") }
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, "Failed to install $packageName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACTION_INSTALL_STATUS -> {
|
||||||
|
val packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
|
||||||
|
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)
|
||||||
|
val extra = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
||||||
|
|
||||||
|
if (inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
|
||||||
|
promptUser(intent, context)
|
||||||
|
} else {
|
||||||
|
postStatus(status, packageName, extra, context)
|
||||||
|
notifyInstallation(context, packageName!!, status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun notifyInstallation(context: Context, packageName: String, status: Int) {
|
||||||
|
val notificationManager =
|
||||||
|
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
val content = if (status == PackageInstaller.STATUS_SUCCESS) {
|
||||||
|
context.getString(R.string.installer_status_success)
|
||||||
|
} else {
|
||||||
|
AppInstaller.getErrorString(context, status)
|
||||||
|
}
|
||||||
|
val notification = NotificationUtil.getInstallNotification(
|
||||||
|
context,
|
||||||
|
App(packageName).apply {
|
||||||
|
if (status == PackageInstaller.STATUS_SUCCESS) {
|
||||||
|
val appInfo = context.packageManager.getApplicationInfo(packageName, 0)
|
||||||
|
displayName = context.packageManager.getApplicationLabel(appInfo).toString()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content
|
||||||
|
)
|
||||||
|
notificationManager.notify(packageName.hashCode(), notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun promptUser(intent: Intent, context: Context) {
|
||||||
|
val confirmationIntent =
|
||||||
|
IntentCompat.getParcelableExtra(intent, Intent.EXTRA_INTENT, Intent::class.java)
|
||||||
|
|
||||||
|
confirmationIntent?.let {
|
||||||
|
it.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
|
||||||
|
it.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, "com.android.vending")
|
||||||
|
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
|
||||||
|
try {
|
||||||
|
context.startActivity(it)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, "Failed to trigger installation!", exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun postStatus(status: Int, packageName: String?, extra: String?, context: Context) {
|
||||||
|
when (status) {
|
||||||
|
PackageInstaller.STATUS_SUCCESS -> {
|
||||||
|
EventBus.getDefault().post(
|
||||||
|
InstallerEvent.Success(
|
||||||
|
packageName,
|
||||||
|
context.getString(R.string.installer_status_success)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageInstaller.STATUS_FAILURE_ABORTED -> {
|
||||||
|
EventBus.getDefault().post(
|
||||||
|
InstallerEvent.Cancelled(
|
||||||
|
packageName,
|
||||||
|
AppInstaller.getErrorString(context, status)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
EventBus.getDefault().post(
|
||||||
|
InstallerEvent.Failed(
|
||||||
|
packageName,
|
||||||
|
AppInstaller.getErrorString(context, status),
|
||||||
|
extra
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun inForeground(): Boolean {
|
||||||
|
return ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,10 +135,10 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
|
|
||||||
// Notify for installation
|
// Notify for installation
|
||||||
Intent(appContext, InstallReceiver::class.java).also {
|
Intent(appContext, InstallReceiver::class.java).also {
|
||||||
|
it.action = InstallReceiver.ACTION_INSTALL_APP
|
||||||
it.putExtra(Constants.STRING_APP, app.packageName)
|
it.putExtra(Constants.STRING_APP, app.packageName)
|
||||||
it.putExtra(Constants.STRING_VERSION, app.versionCode)
|
it.putExtra(Constants.STRING_VERSION, app.versionCode)
|
||||||
appContext.sendBroadcast(it)
|
appContext.sendBroadcast(it)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the app from the list
|
// Remove the app from the list
|
||||||
|
|||||||
@@ -268,12 +268,15 @@ object NotificationUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getInstallNotification(context: Context, app: App, content: String?): Notification {
|
fun getInstallNotification(context: Context, app: App, content: String?): Notification {
|
||||||
val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT)
|
val builder =
|
||||||
builder.color = context.getStyledAttributeColor(R.color.colorAccent)
|
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT).apply {
|
||||||
builder.setSmallIcon(R.drawable.ic_install)
|
color = context.getStyledAttributeColor(R.color.colorAccent)
|
||||||
builder.setContentTitle(app.displayName)
|
setSmallIcon(R.drawable.ic_install)
|
||||||
builder.setContentText(content)
|
setContentTitle(app.displayName)
|
||||||
builder.setSubText(app.packageName)
|
setContentText(content)
|
||||||
|
setContentIntent(getContentIntentForDetails(context, app))
|
||||||
|
setSubText(app.packageName)
|
||||||
|
}
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user