Skip to content

Commit af67a1d

Browse files
fix: catch SecurityException from getExternalStoragePublicDirectory on Samsung SDK 35
1 parent b3f4a03 commit af67a1d

8 files changed

Lines changed: 21 additions & 7 deletions

File tree

app/src/main/java/me/bmax/apatch/ui/screen/ExecuteAPMAction.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import kotlinx.coroutines.withContext
4141
import me.bmax.apatch.APApplication
4242
import me.bmax.apatch.R
4343
import me.bmax.apatch.ui.component.KeyEventBlocker
44+
import me.bmax.apatch.util.getSafeDownloadsDir
4445
import me.bmax.apatch.util.runAPModuleAction
4546
import me.bmax.apatch.util.ui.LocalSnackbarHost
4647
import java.io.File
@@ -119,7 +120,7 @@ fun ExecuteAPMActionScreen(navigator: DestinationsNavigator, moduleId: String) {
119120
val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
120121
val date = format.format(Date())
121122
val file = File(
122-
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
123+
getSafeDownloadsDir(me.bmax.apatch.apApp),
123124
"APatch_apm_action_log_${date}.log"
124125
)
125126
file.writeText(fullLogBuffer.toString())

app/src/main/java/me/bmax/apatch/ui/screen/Install.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import kotlinx.coroutines.launch
4949
import kotlinx.coroutines.withContext
5050
import me.bmax.apatch.R
5151
import me.bmax.apatch.ui.component.KeyEventBlocker
52+
import me.bmax.apatch.util.getSafeDownloadsDir
5253
import me.bmax.apatch.util.installModule
5354
import me.bmax.apatch.util.BulkInstallManager
5455
import me.bmax.apatch.util.reboot
@@ -143,7 +144,7 @@ fun InstallScreen(navigator: DestinationsNavigator, uri: Uri, type: MODULE_TYPE)
143144
val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
144145
val date = format.format(Date())
145146
val file = File(
146-
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
147+
getSafeDownloadsDir(context),
147148
"APatch_install_${type}_log_${date}.log"
148149
)
149150
file.writeText(fullLogBuffer.toString())

app/src/main/java/me/bmax/apatch/ui/screen/ScriptExecutionLogScreen.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import me.bmax.apatch.APApplication
4747
import me.bmax.apatch.R
4848
import me.bmax.apatch.apApp
4949
import me.bmax.apatch.data.ScriptInfo
50+
import me.bmax.apatch.util.getSafeDownloadsDir
5051
import me.bmax.apatch.util.ui.AnsiUtils
5152
import me.bmax.apatch.util.ui.LocalSnackbarHost
5253
import java.io.File
@@ -239,7 +240,7 @@ fun ScriptExecutionLogScreen(
239240
val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault())
240241
val date = format.format(Date())
241242
val file = File(
242-
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
243+
getSafeDownloadsDir(context),
243244
"FolkPatch/${scriptInfo.alias}_${date}.log"
244245
)
245246
file.writeText(fullLogBuffer.toString())

app/src/main/java/me/bmax/apatch/ui/screen/settings/BackupSettings.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ fun BackupSettingsContent(
8484
ExpressiveCard(
8585
flat = flat,
8686
onClick = {
87-
val backupDir = java.io.File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS), "FolkPatch/ModuleBackups")
87+
val backupDir = java.io.File(me.bmax.apatch.util.getSafeDownloadsDir(context), "FolkPatch/ModuleBackups")
8888
if (!backupDir.exists()) backupDir.mkdirs()
8989

9090
try {

app/src/main/java/me/bmax/apatch/ui/viewmodel/PatchesViewModel.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import me.bmax.apatch.BuildConfig
2828
import me.bmax.apatch.R
2929
import me.bmax.apatch.apApp
3030
import me.bmax.apatch.util.Version
31+
import me.bmax.apatch.util.getSafeDownloadsDir
3132
import me.bmax.apatch.util.copyAndClose
3233
import me.bmax.apatch.util.copyAndCloseOut
3334
import me.bmax.apatch.util.createRootShell
@@ -667,7 +668,7 @@ class PatchesViewModel : ViewModel() {
667668
APApplication.markNeedReboot()
668669
} else if (mode == PatchMode.PATCH_ONLY) {
669670
val newBootFile = patchDir.getChildFile("new-boot.img")
670-
val outDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
671+
val outDir = getSafeDownloadsDir(apApp)
671672
if (!outDir.exists()) outDir.mkdirs()
672673
val outPath = File(outDir, outFilename)
673674
val inputUri = newBootFile.getUri(apApp)

app/src/main/java/me/bmax/apatch/util/Downloader.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ import androidx.compose.runtime.Composable
1313
import androidx.compose.runtime.DisposableEffect
1414
import me.bmax.apatch.apApp
1515
import androidx.core.content.ContextCompat
16+
import java.io.File
17+
18+
fun getSafeDownloadsDir(context: Context): File {
19+
return try {
20+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
21+
} catch (_: SecurityException) {
22+
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
23+
?: File(context.filesDir, "Download")
24+
}
25+
}
1626

1727
@SuppressLint("Range")
1828
fun download(

app/src/main/java/me/bmax/apatch/util/ModuleBackupUtils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ object ModuleBackupUtils {
5656
val localJob = async {
5757
if (APApplication.sharedPreferences.getBoolean("auto_backup_module", false)) {
5858
try {
59-
val baseBackupDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "FolkPatch/ModuleBackups")
59+
val baseBackupDir = File(getSafeDownloadsDir(me.bmax.apatch.apApp), "FolkPatch/ModuleBackups")
6060
// Use subDir (APM/KPM) to separate backups
6161
val backupDir = File(baseBackupDir, subDir)
6262

app/src/main/java/me/bmax/apatch/util/ThemeDownloader.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class ThemeDownloader(private val context: Context) {
100100
*/
101101
private fun getExternalThemesDir(): File {
102102
val externalDir = File(
103-
android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS),
103+
getSafeDownloadsDir(context),
104104
"FolkPatch/Themes"
105105
)
106106
if (!externalDir.exists()) {

0 commit comments

Comments
 (0)