mirror of
https://github.com/whyorean/AuroraStore.git
synced 2026-06-16 03:31:02 -04:00
DownloadWorker: Trigger app installation on success
* Transparent dummy activity to trigger installation of apps from notification Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -91,6 +91,11 @@
|
||||
<nav-graph android:value="@navigation/mobile_navigation" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".data.activity.InstallActivity"
|
||||
android:exported="false"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
|
||||
<service android:name=".data.service.NotificationService" />
|
||||
<service android:name=".data.installer.InstallerService" />
|
||||
<service android:name=".data.service.UpdateService" />
|
||||
@@ -123,5 +128,8 @@
|
||||
<receiver android:name=".data.receiver.DownloadResumeReceiver" />
|
||||
<receiver android:name=".data.receiver.DownloadPauseReceiver" />
|
||||
<receiver android:name=".data.receiver.DownloadCancelReceiver" />
|
||||
<receiver
|
||||
android:name=".data.receiver.InstallReceiver"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -23,6 +23,7 @@ object Constants {
|
||||
const val INT_EXTRA = "INT_EXTRA"
|
||||
const val FLOAT_EXTRA = "FLOAT_EXTRA"
|
||||
const val STRING_APP = "STRING_APP"
|
||||
const val STRING_VERSION = "STRING_VERSION"
|
||||
const val STRING_EXTRA = "STRING_EXTRA"
|
||||
const val BROWSE_EXTRA = "BROWSE_EXTRA"
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.aurora.store.data.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.aurora.Constants
|
||||
import com.aurora.store.data.installer.AppInstaller
|
||||
import com.aurora.store.util.PathUtil
|
||||
import java.io.File
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class InstallActivity : Activity() {
|
||||
|
||||
private val TAG = InstallActivity::class.java.simpleName
|
||||
|
||||
private lateinit var packageName: String
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
packageName = intent.extras?.getString(Constants.STRING_APP) ?: String()
|
||||
val version = intent.extras?.getInt(Constants.STRING_VERSION)
|
||||
if (packageName.isNotBlank() && version != null) {
|
||||
try {
|
||||
val downloadDir =
|
||||
File(PathUtil.getAppDownloadDir(this, packageName, version).pathString)
|
||||
AppInstaller.getInstance(this).getPreferredInstaller()
|
||||
.install(
|
||||
packageName,
|
||||
downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") }
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed to install $packageName")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
@@ -21,16 +21,32 @@ package com.aurora.store.data.receiver
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.aurora.Constants
|
||||
import com.aurora.store.data.installer.AppInstaller
|
||||
import com.aurora.store.util.PathUtil
|
||||
import java.io.File
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class InstallReceiver : BroadcastReceiver() {
|
||||
|
||||
private val TAG = InstallReceiver::class.java.simpleName
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val extras = intent.extras
|
||||
if (extras != null) {
|
||||
/*val packageName = extras.getString(Constants.INTENT_PACKAGE_NAME, "")
|
||||
val versionString = extras.getString(Constants.DOWNLOAD_VERSION_CODE)
|
||||
if (!packageName.isEmpty() && versionString != null) {
|
||||
AuroraApplication.getInstaller().installSplit(packageName, versionString.toInt())
|
||||
}*/
|
||||
val packageName = intent.extras?.getString(Constants.STRING_APP) ?: String()
|
||||
val version = intent.extras?.getInt(Constants.STRING_VERSION)
|
||||
if (packageName.isNotBlank() && version != null) {
|
||||
try {
|
||||
val downloadDir =
|
||||
File(PathUtil.getAppDownloadDir(context, packageName, version).pathString)
|
||||
AppInstaller.getInstance(context).getPreferredInstaller()
|
||||
.install(
|
||||
packageName,
|
||||
downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") }
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed to install $packageName")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.aurora.store.data.work
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
|
||||
import android.util.Log
|
||||
import androidx.work.CoroutineWorker
|
||||
@@ -13,6 +14,7 @@ import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.OutOfQuotaPolicy
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
import com.aurora.Constants
|
||||
import com.aurora.extensions.copyTo
|
||||
import com.aurora.extensions.isQAndAbove
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
@@ -21,6 +23,7 @@ import com.aurora.store.data.model.DownloadStatus
|
||||
import com.aurora.store.data.model.Request
|
||||
import com.aurora.store.data.network.HttpClient
|
||||
import com.aurora.store.data.providers.AuthProvider
|
||||
import com.aurora.store.data.receiver.InstallReceiver
|
||||
import com.aurora.store.util.NotificationUtil
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.google.gson.Gson
|
||||
@@ -63,7 +66,6 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var appDownloadDir: Path
|
||||
private var downloading = false
|
||||
|
||||
private val TAG = DownloadWorker::class.java.simpleName
|
||||
@@ -81,7 +83,6 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
||||
withContext(Dispatchers.Default) {
|
||||
try {
|
||||
app = gson.fromJson(inputData.getString(DOWNLOAD_DATA), App::class.java)
|
||||
appDownloadDir = Path(PathUtil.getPackageDirectory(appContext, app.packageName))
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed parsing requested app!", exception)
|
||||
notifyStatus(DownloadStatus.FAILED)
|
||||
@@ -101,7 +102,7 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
||||
}
|
||||
|
||||
// Download and verify all files exists
|
||||
Path(appDownloadDir.absolutePathString(), app.versionCode.toString()).createDirectories()
|
||||
PathUtil.getAppDownloadDir(appContext, app.packageName, app.versionCode).createDirectories()
|
||||
|
||||
val requestList = getDownloadRequest(files)
|
||||
requestList.forEach { request ->
|
||||
@@ -115,6 +116,14 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
||||
// Mark download as completed
|
||||
notifyStatus(DownloadStatus.COMPLETED)
|
||||
Log.i(TAG, "Finished downloading ${app.packageName}")
|
||||
|
||||
// Notify for installation
|
||||
Intent(appContext, InstallReceiver::class.java).also {
|
||||
it.putExtra(Constants.STRING_APP, app.packageName)
|
||||
it.putExtra(Constants.STRING_VERSION, app.versionCode)
|
||||
appContext.sendBroadcast(it)
|
||||
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@ import com.aurora.extensions.isMAndAbove
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.store.MainActivity
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.activity.InstallActivity
|
||||
import com.aurora.store.data.model.DownloadStatus
|
||||
import com.aurora.store.data.receiver.DownloadCancelReceiver
|
||||
import com.aurora.store.data.receiver.DownloadPauseReceiver
|
||||
import com.aurora.store.data.receiver.DownloadResumeReceiver
|
||||
import com.aurora.store.data.receiver.InstallReceiver
|
||||
import com.tonyodev.fetch2.Download
|
||||
import com.tonyodev.fetch2.FetchGroup
|
||||
import com.tonyodev.fetch2.Status
|
||||
@@ -231,6 +231,13 @@ object NotificationUtil {
|
||||
builder.setAutoCancel(true)
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
builder.setContentIntent(getContentIntentForDetails(context, app))
|
||||
builder.addAction(
|
||||
NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_install,
|
||||
context.getString(R.string.action_install),
|
||||
getInstallIntent(context, app.packageName, app.versionCode)
|
||||
).build()
|
||||
)
|
||||
}
|
||||
|
||||
DownloadStatus.DOWNLOADING, DownloadStatus.QUEUED -> {
|
||||
@@ -314,17 +321,22 @@ object NotificationUtil {
|
||||
.createPendingIntent()
|
||||
}
|
||||
|
||||
private fun getInstallIntent(context: Context, packageName: String): PendingIntent {
|
||||
val intent = Intent(context, InstallReceiver::class.java)
|
||||
intent.putExtra(Constants.STRING_EXTRA, packageName)
|
||||
val flags = if (isMAndAbove())
|
||||
private fun getInstallIntent(
|
||||
context: Context,
|
||||
packageName: String,
|
||||
version: Int
|
||||
): PendingIntent {
|
||||
val intent = Intent(context, InstallActivity::class.java).apply {
|
||||
putExtra(Constants.STRING_APP, packageName)
|
||||
putExtra(Constants.STRING_VERSION, version)
|
||||
}
|
||||
val flags = if (isMAndAbove()) {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
else PendingIntent.FLAG_CANCEL_CURRENT
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
packageName.hashCode(),
|
||||
intent,
|
||||
flags
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
return PendingIntent.getActivity(
|
||||
context, packageName.hashCode(), intent, flags
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ import android.os.Environment
|
||||
import com.aurora.extensions.isRAndAbove
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.gplayapi.data.models.File
|
||||
import java.nio.file.Path
|
||||
import java.util.UUID
|
||||
import kotlin.io.path.Path
|
||||
|
||||
fun Context.getInternalBaseDirectory(): String {
|
||||
return (getExternalFilesDir(null) ?: filesDir).path
|
||||
@@ -52,6 +54,10 @@ object PathUtil {
|
||||
return getPackageDirectory(context, packageName) + "/$versionCode"
|
||||
}
|
||||
|
||||
fun getAppDownloadDir(context: Context, packageName: String, versionCode: Int): Path {
|
||||
return Path(getPackageDirectory(context, packageName), versionCode.toString())
|
||||
}
|
||||
|
||||
fun getApkDownloadFile(context: Context, app: App, file: File): String {
|
||||
return getVersionDirectory(context, app.packageName, app.versionCode) + "/${file.name}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user