Allow choosing custom download directory

This commit is contained in:
Rahul Patel
2023-10-17 05:44:34 +05:30
parent 13f1459827
commit 4fe7d453f5
9 changed files with 153 additions and 24 deletions

View File

@@ -31,7 +31,7 @@ import java.util.zip.ZipOutputStream
class ApkCopier(private val context: Context, private val packageName: String) {
fun copy() {
val destination = File(PathUtil.getBaseCopyDirectory())
val destination = File(PathUtil.getBaseCopyDirectory(context))
destination.let {
if (it.exists()) {
@@ -55,7 +55,7 @@ class ApkCopier(private val context: Context, private val packageName: String) {
/*Add Split APKs*/
fileList.addAll(getSplitAPKs(packageInfo))
}
bundleAllAPKs(fileList)
bundleAllAPKs(context, fileList)
}
private fun getBaseApk(packageInfo: PackageInfo?): File? {
@@ -75,10 +75,10 @@ class ApkCopier(private val context: Context, private val packageName: String) {
return fileList
}
private fun bundleAllAPKs(fileList: List<File?>) {
private fun bundleAllAPKs(context: Context, fileList: List<File?>) {
try {
val fileOutputStream =
FileOutputStream(PathUtil.getBaseCopyDirectory() + "$packageName.zip")
FileOutputStream(PathUtil.getBaseCopyDirectory(context) + "$packageName.zip")
val zipOutputStream = ZipOutputStream(fileOutputStream)
for (file in fileList) {

View File

@@ -21,6 +21,7 @@ package com.aurora.store.util
import android.content.Context
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.util.UUID
@@ -33,7 +34,7 @@ object PathUtil {
private fun getDownloadDirectory(context: Context): String {
return if (context.isExternalStorageEnable()) {
getExternalPath()
getExternalPath(context)
} else {
context.getInternalBaseDirectory()
}
@@ -59,15 +60,22 @@ object PathUtil {
return getVersionDirectory(context, packageName, versionCode)
}
fun getExternalPath(): String {
val auroraDir =
fun getExternalPath(context: Context): String {
val defaultDir =
java.io.File("${Environment.getExternalStorageDirectory().absolutePath}/Aurora/Store")
auroraDir.mkdirs()
return auroraDir.absolutePath
if (!defaultDir.exists())
defaultDir.mkdirs()
return Preferences.getString(
context,
Preferences.PREFERENCE_DOWNLOAD_DIRECTORY,
defaultDir.absolutePath
)
}
fun getBaseCopyDirectory(): String {
return "${getExternalPath()}/Exports/"
fun getBaseCopyDirectory(context: Context): String {
return "${getExternalPath(context)}/Exports/"
}
private fun getObbDownloadPath(app: App): String {
@@ -94,6 +102,20 @@ object PathUtil {
file.createNewFile()
return file
}
fun canWriteToDirectory(context: Context, directoryPath: String): Boolean {
val directory = if (directoryPath.startsWith("/")) {
java.io.File(directoryPath)
} else {
java.io.File(context.getExternalFilesDir(null), directoryPath)
}
return if (isRAndAbove()) {
Environment.isExternalStorageManager() && directory.exists() && directory.canWrite()
} else {
isExternalStorageAccessible(context) && directory.exists() && directory.canWrite()
}
}
}
fun Context.isExternalStorageEnable(): Boolean {

View File

@@ -0,0 +1,13 @@
package com.aurora.store.util
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
fun isExternalStorageAccessible(context: Context): Boolean {
return ActivityCompat.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
}

View File

@@ -49,6 +49,7 @@ object Preferences {
const val PREFERENCE_DOWNLOAD_ACTIVE = "PREFERENCE_DOWNLOAD_ACTIVE"
const val PREFERENCE_DOWNLOAD_EXTERNAL = "PREFERENCE_DOWNLOAD_EXTERNAL"
const val PREFERENCE_DOWNLOAD_DIRECTORY = "PREFERENCE_DOWNLOAD_DIRECTORY"
const val PREFERENCE_DOWNLOAD_WIFI = "PREFERENCE_DOWNLOAD_WIFI"
const val PREFERENCE_TOS_READ = "PREFERENCE_TOS_READ"
@@ -89,8 +90,8 @@ object Preferences {
getPrefs(context).edit().putBoolean(key, value).apply()
}
fun getString(context: Context, key: String): String {
return getPrefs(context).getString(key, "").toString()
fun getString(context: Context, key: String, default: String = ""): String {
return getPrefs(context).getString(key, default).toString()
}
fun getInteger(context: Context, key: String): Int {

View File

@@ -20,6 +20,7 @@
package com.aurora.store.view.ui.onboarding
import android.os.Bundle
import android.os.Environment
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@@ -31,12 +32,14 @@ import com.aurora.extensions.isSAndAbove
import com.aurora.store.R
import com.aurora.store.data.work.UpdateWorker
import com.aurora.store.databinding.FragmentOnboardingBinding
import com.aurora.store.util.PathUtil
import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_INSTALL
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT_SELECTED_TAB
import com.aurora.store.util.Preferences.PREFERENCE_DOWNLOAD_ACTIVE
import com.aurora.store.util.Preferences.PREFERENCE_DOWNLOAD_DIRECTORY
import com.aurora.store.util.Preferences.PREFERENCE_DOWNLOAD_EXTERNAL
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_FDROID
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_GOOGLE
@@ -155,6 +158,7 @@ class OnboardingFragment : Fragment(R.layout.fragment_onboarding) {
/*Downloader*/
save(PREFERENCE_DOWNLOAD_ACTIVE, 3)
save(PREFERENCE_DOWNLOAD_EXTERNAL, false)
save(PREFERENCE_DOWNLOAD_DIRECTORY, PathUtil.getExternalPath(requireContext()))
/*Network*/
save(PREFERENCE_INSECURE_ANONYMOUS, false)

View File

@@ -38,6 +38,7 @@ import com.aurora.store.BuildConfig
import com.aurora.store.R
import com.aurora.store.data.model.Permission
import com.aurora.store.databinding.FragmentOnboardingPermissionsBinding
import com.aurora.store.util.isExternalStorageAccessible
import com.aurora.store.view.epoxy.views.preference.PermissionViewModel_
import com.aurora.store.view.ui.commons.BaseFragment
@@ -113,10 +114,8 @@ class PermissionsFragment : BaseFragment(R.layout.fragment_onboarding_permission
}
binding.epoxyRecycler.withModels {
val writeExternalStorage = if (!isRAndAbove()) ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED else true
val writeExternalStorage =
if (!isRAndAbove()) isExternalStorageAccessible(requireContext()) else true
val postNotifications = if (isTAndAbove()) ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.POST_NOTIFICATIONS

View File

@@ -19,18 +19,61 @@
package com.aurora.store.view.ui.preferences
import android.Manifest
import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.Toolbar
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import com.aurora.extensions.isRAndAbove
import com.aurora.extensions.toast
import com.aurora.store.R
import com.aurora.store.util.PathUtil
import com.aurora.store.util.Preferences
import com.aurora.store.util.isExternalStorageAccessible
import com.aurora.store.util.save
class DownloadPreference : PreferenceFragmentCompat() {
private lateinit var startForStorageManagerResult: ActivityResultLauncher<Intent>
private lateinit var startForPermissions: ActivityResultLauncher<String>
private var downloadDirectoryPreference: Preference? = null
private var downloadExternalPreference: SwitchPreferenceCompat? = null
private var autoDeletePreference: SwitchPreferenceCompat? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startForStorageManagerResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
val state = isRAndAbove() && Environment.isExternalStorageManager()
if (state) {
downloadDirectoryPreference?.summary =
PathUtil.getExternalPath(requireContext())
} else {
notifyPermissionState(isRAndAbove() && Environment.isExternalStorageManager())
}
}
startForPermissions =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
notifyPermissionState(it)
} else {
downloadExternalPreference?.isChecked = false
}
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences_download, rootKey)
}
@@ -43,17 +86,41 @@ class DownloadPreference : PreferenceFragmentCompat() {
setNavigationOnClickListener { findNavController().navigateUp() }
}
val downloadExternalPreference: SwitchPreferenceCompat? =
findPreference(Preferences.PREFERENCE_DOWNLOAD_EXTERNAL)
val autoDeletePreference: SwitchPreferenceCompat? =
findPreference(Preferences.PREFERENCE_AUTO_DELETE)
downloadDirectoryPreference = findPreference(Preferences.PREFERENCE_DOWNLOAD_DIRECTORY)
downloadExternalPreference = findPreference(Preferences.PREFERENCE_DOWNLOAD_EXTERNAL)
autoDeletePreference = findPreference(Preferences.PREFERENCE_AUTO_DELETE)
downloadDirectoryPreference?.let { preference ->
preference.summary = PathUtil.getExternalPath(requireContext())
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { it, newValue ->
if (PathUtil.canWriteToDirectory(requireContext(), newValue.toString())) {
it.summary = newValue.toString()
save(Preferences.PREFERENCE_DOWNLOAD_DIRECTORY, newValue.toString())
true
} else {
toast(R.string.pref_download_directory_error)
false
}
}
}
downloadExternalPreference?.let { switchPreferenceCompat ->
switchPreferenceCompat.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
val checked = newValue.toString().toBoolean()
if (checked) {
if (isRAndAbove() && !Environment.isExternalStorageManager()) {
startForStorageManagerResult.launch(
Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
)
}
if (!isRAndAbove() && !isExternalStorageAccessible(requireContext())) {
startForPermissions.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
autoDeletePreference?.let {
if (checked) {
it.isEnabled = true
@@ -67,4 +134,18 @@ class DownloadPreference : PreferenceFragmentCompat() {
}
}
}
}
private fun notifyPermissionState(state: Boolean) {
if (state) {
toast(R.string.toast_permission_granted)
} else {
toast(R.string.permissions_denied)
}
}
override fun onDestroy() {
super.onDestroy()
startForStorageManagerResult.unregister()
startForPermissions.unregister()
}
}