DownloadMenuSheet: Allow to export downloaded files

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2024-04-16 12:04:32 +05:30
parent 5f714e624b
commit 92771bbaec
5 changed files with 67 additions and 8 deletions

View File

@@ -33,7 +33,7 @@ object ApkCopier {
private const val TAG = "ApkCopier"
fun copy(context: Context, packageName: String, uri: Uri) {
fun copyInstalledApp(context: Context, packageName: String, uri: Uri) {
val packageInfo = getPackageInfo(context, packageName, PackageManager.GET_META_DATA)
val baseApk = getBaseApk(packageInfo)
val fileList: MutableList<File?> = mutableListOf()
@@ -47,6 +47,14 @@ object ApkCopier {
bundleAllAPKs(context, fileList.filterNotNull(), uri)
}
fun copyDownloadedApp(context: Context, packageName: String, versionCode: Int, uri: Uri) {
return bundleAllAPKs(
context,
PathUtil.getAppDownloadDir(context, packageName, versionCode).listFiles()!!.toList(),
uri
)
}
private fun getBaseApk(packageInfo: PackageInfo?): File? {
return if (packageInfo?.applicationInfo != null) {
File(packageInfo.applicationInfo.sourceDir)

View File

@@ -57,7 +57,7 @@ class AppMenuSheet : BottomSheetDialogFragment(R.layout.sheet_app_menu) {
private val requestDocumentCreation =
registerForActivityResult(ActivityResultContracts.CreateDocument(exportMimeType)) {
if (it != null) {
viewModel.copyApk(requireContext(), args.app.packageName, it)
viewModel.copyInstalledApp(requireContext(), args.app.packageName, it)
} else {
toast(R.string.failed_apk_export)
}

View File

@@ -22,6 +22,8 @@ package com.aurora.store.view.ui.sheets
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.viewModels
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.navArgs
@@ -32,6 +34,8 @@ import com.aurora.store.data.installer.AppInstaller
import com.aurora.store.data.model.DownloadStatus
import com.aurora.store.databinding.SheetDownloadMenuBinding
import com.aurora.store.util.DownloadWorkerUtil
import com.aurora.store.util.PathUtil
import com.aurora.store.viewmodel.sheets.SheetsViewModel
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@@ -46,9 +50,27 @@ class DownloadMenuSheet : BottomSheetDialogFragment(R.layout.sheet_download_menu
private var _binding: SheetDownloadMenuBinding? = null
private val binding get() = _binding!!
private val viewModel: SheetsViewModel by viewModels()
private val args: DownloadMenuSheetArgs by navArgs()
private val playStoreURL = "https://play.google.com/store/apps/details?id="
private val exportMimeType = "application/zip"
private val requestDocumentCreation =
registerForActivityResult(ActivityResultContracts.CreateDocument(exportMimeType)) {
if (it != null) {
viewModel.copyDownloadedApp(
requireContext(),
args.download.packageName,
args.download.versionCode,
it
)
} else {
toast(R.string.failed_apk_export)
}
dismissAllowingStateLoss()
}
@Inject
lateinit var downloadWorkerUtil: DownloadWorkerUtil
@@ -60,24 +82,37 @@ class DownloadMenuSheet : BottomSheetDialogFragment(R.layout.sheet_download_menu
_binding = SheetDownloadMenuBinding.bind(view)
with(binding.navigationView) {
val downloadCompleted = args.download.downloadStatus == DownloadStatus.COMPLETED
val downloadDir = PathUtil.getAppDownloadDir(
requireContext(),
args.download.packageName,
args.download.versionCode
)
menu.findItem(R.id.action_cancel).isVisible = !args.download.isFinished
menu.findItem(R.id.action_clear).isVisible = args.download.isFinished
menu.findItem(R.id.action_install).isVisible =
args.download.downloadStatus == DownloadStatus.COMPLETED
menu.findItem(R.id.action_install).isVisible = downloadCompleted
menu.findItem(R.id.action_local).isVisible =
downloadCompleted && downloadDir.listFiles() != null
setNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.action_install -> install()
R.id.action_install -> {
install()
dismissAllowingStateLoss()
}
R.id.action_copy -> {
requireContext().copyToClipBoard(
"${playStoreURL}${args.download.packageName}"
)
requireContext().toast(requireContext().getString(R.string.toast_clipboard_copied))
dismissAllowingStateLoss()
}
R.id.action_cancel -> {
findViewTreeLifecycleOwner()?.lifecycleScope?.launch(NonCancellable) {
downloadWorkerUtil.cancelDownload(args.download.packageName)
}
dismissAllowingStateLoss()
}
R.id.action_clear -> {
findViewTreeLifecycleOwner()?.lifecycleScope?.launch(NonCancellable) {
@@ -86,9 +121,12 @@ class DownloadMenuSheet : BottomSheetDialogFragment(R.layout.sheet_download_menu
args.download.versionCode
)
}
dismissAllowingStateLoss()
}
R.id.action_local -> {
requestDocumentCreation.launch("${args.download.packageName}.zip")
}
}
dismissAllowingStateLoss()
false
}
}

View File

@@ -40,9 +40,19 @@ class SheetsViewModel : ViewModel() {
}
}
fun copyApk(context: Context, packageName: String, uri: Uri) {
fun copyInstalledApp(context: Context, packageName: String, uri: Uri) {
viewModelScope.launch(Dispatchers.IO) {
ApkCopier.copy(context, packageName, uri)
ApkCopier.copyInstalledApp(context, packageName, uri)
}
}
fun copyDownloadedApp(context: Context, packageName: String, versionCode: Int, uri: Uri) {
viewModelScope.launch(Dispatchers.IO) {
try {
ApkCopier.copyDownloadedApp(context, packageName, versionCode, uri)
} catch (exception: Exception) {
Log.e(TAG, "Failed to copy downloads", exception)
}
}
}
}

View File

@@ -18,6 +18,9 @@
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_local"
android:title="@string/action_get_local_apk" />
<item
android:id="@+id/action_install"
android:title="@string/action_install" />