Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1a3ffcc
Fix "Replace characters on save as function, FileNotFoundException" #250
Sep 25, 2025
0b63f83
Update CHANGELOG.md
jguegel Sep 25, 2025
41d05cf
Update app/src/main/kotlin/org/fossify/filemanager/activities/SaveAsA…
jguegel Sep 26, 2025
c7f6bf9
Update CHANGELOG.md
jguegel Sep 26, 2025
01a2dbd
Update CHANGELOG.md
jguegel Sep 26, 2025
6085042
Merge branch 'FossifyOrg:main' into main
jguegel Sep 26, 2025
3528a95
Merge branch 'FossifyOrg:main' into main
jguegel Sep 26, 2025
24e156c
Merge branch 'FossifyOrg:main' into main
Sep 26, 2025
e3bd385
Merge remote-tracking branch 'origin/main'
Sep 26, 2025
21b2aaa
Update CHANGELOG.md
jguegel Sep 26, 2025
204c879
fix PR Feedback
Sep 26, 2025
2a88a59
Merge remote-tracking branch 'origin/main'
Sep 26, 2025
1b67e61
fix duplicated code by moving it to SimpleActivity.kt
Sep 26, 2025
2a5026e
moved handleStoragePermissions() to SimpleActivity.kt from MainActivi…
Sep 26, 2025
588a046
adjusted toast in try catch in storage permission action
Sep 26, 2025
0dcf18c
catch ActivityNotFoundException with fallback of SecurityException
Sep 26, 2025
6caecb3
fix hardcoded error toast
Sep 26, 2025
38d99ad
fix auto update after extract #194
Sep 26, 2025
c2ea0bb
fix auto update after extract by opening extracted folder #194
Sep 26, 2025
e76565d
Apply suggestions from code review
jguegel Sep 27, 2025
d6b7efb
remove indent
Sep 27, 2025
c50e835
adjust changelog
jguegel Sep 27, 2025
3e88966
Merge remote-tracking branch 'origin/main' into auto-update-tab-after…
Sep 27, 2025
4bcb2d2
Update CHANGELOG.md
jguegel Sep 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fixed folders showing up incorrectly as files in copy/move dialog ([#267])
- Fixed error when saving files with unsupported characters ([#250])
- Fixed missing permission prompt on initial "Save as" launch ([#85])
- Fixed auto-refresh after decompressing file by opening into decompressed folder ([#194])

## [1.2.3] - 2025-09-15
### Fixed
Expand Down Expand Up @@ -76,6 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#251]: https://github.com/FossifyOrg/File-Manager/issues/251
[#267]: https://github.com/FossifyOrg/File-Manager/issues/267
[#250]: https://github.com/FossifyOrg/File-Manager/issues/250
[#85]: https://github.com/FossifyOrg/File-Manager/issues/85
[#194]: https://github.com/FossifyOrg/File-Manager/issues/194

[Unreleased]: https://github.com/FossifyOrg/File-Manager/compare/1.2.3...HEAD
[1.2.3]: https://github.com/FossifyOrg/File-Manager/compare/1.2.2...1.2.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import java.io.File
class DecompressActivity : SimpleActivity() {
companion object {
private const val PASSWORD = "password"
var onDecompressFinished: ((String) -> Unit)? = null
}

private val binding by viewBinding(ActivityDecompressBinding::inflate)
Expand Down Expand Up @@ -192,9 +193,13 @@ class DecompressActivity : SimpleActivity() {
fos!!.close()
outputFile.setLastModified(entry)
}
runOnUiThread {
toast(R.string.decompression_successful)
val extractedFolder = "$destination/${filename.substringBeforeLast(".")}"
onDecompressFinished?.invoke(extractedFolder)
finish()
}

toast(R.string.decompression_successful)
finish()
}
} catch (e: Exception) {
showErrorToast(e)
Expand Down Expand Up @@ -232,7 +237,7 @@ class DecompressActivity : SimpleActivity() {
} catch (passwordException: ZipException) {
if (passwordException.type == Type.WRONG_PASSWORD) {
if (password != null) {
toast(getString(R.string.invalid_password))
toast(R.string.invalid_password)
passwordDialog?.clearPassword()
} else {
runOnUiThread {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package org.fossify.filemanager.activities

import android.annotation.SuppressLint
import android.app.Activity
import android.content.ClipData
import android.content.Intent
import android.graphics.drawable.Drawable
import android.media.RingtoneManager
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.provider.Settings
import android.widget.ImageView
import android.widget.TextView
import androidx.viewpager.widget.ViewPager
import com.stericson.RootTools.RootTools
import me.grantland.widget.AutofitHelper
import org.fossify.commons.dialogs.ConfirmationAdvancedDialog
import org.fossify.commons.dialogs.RadioGroupDialog
import org.fossify.commons.extensions.appLaunched
import org.fossify.commons.extensions.appLockManager
Expand All @@ -43,7 +38,6 @@ import org.fossify.commons.extensions.launchMoreAppsFromUsIntent
import org.fossify.commons.extensions.onGlobalLayout
import org.fossify.commons.extensions.onTabSelectionChanged
import org.fossify.commons.extensions.sdCardPath
import org.fossify.commons.extensions.showErrorToast
import org.fossify.commons.extensions.toast
import org.fossify.commons.extensions.updateBottomTabItemColors
import org.fossify.commons.extensions.viewBinding
Expand All @@ -59,7 +53,6 @@ import org.fossify.commons.helpers.TAB_RECENT_FILES
import org.fossify.commons.helpers.TAB_STORAGE_ANALYSIS
import org.fossify.commons.helpers.VIEW_TYPE_GRID
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.helpers.isRPlus
import org.fossify.commons.models.FAQItem
import org.fossify.commons.models.RadioItem
import org.fossify.commons.models.Release
Expand All @@ -84,7 +77,6 @@ import java.io.File
class MainActivity : SimpleActivity() {
companion object {
private const val BACK_PRESS_TIMEOUT = 5000
private const val MANAGE_STORAGE_RC = 201
private const val PICKED_PATH = "picked_path"
}

Expand Down Expand Up @@ -127,6 +119,10 @@ class MainActivity : SimpleActivity() {
checkIfRootAvailable()
checkInvalidFavorites()
}

DecompressActivity.onDecompressFinished = { extractedFolder ->
openPath(extractedFolder, true)
}
}

override fun onResume() {
Expand Down Expand Up @@ -281,15 +277,6 @@ class MainActivity : SimpleActivity() {
}
}

@SuppressLint("NewApi")
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
isAskingPermissions = false
if (requestCode == MANAGE_STORAGE_RC && isRPlus()) {
actionOnPermission?.invoke(Environment.isExternalStorageManager())
}
}

private fun updateMenuColors() {
updateStatusbarColor(getProperBackgroundColor())
binding.mainMenu.updateColors()
Expand Down Expand Up @@ -323,38 +310,6 @@ class MainActivity : SimpleActivity() {
}
}

@SuppressLint("InlinedApi")
private fun handleStoragePermission(callback: (granted: Boolean) -> Unit) {
actionOnPermission = null
if (hasStoragePermission()) {
callback(true)
} else {
if (isRPlus()) {
ConfirmationAdvancedDialog(this, "", R.string.access_storage_prompt, R.string.ok, 0, false) { success ->
if (success) {
isAskingPermissions = true
actionOnPermission = callback
try {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.addCategory("android.intent.category.DEFAULT")
intent.data = Uri.parse("package:$packageName")
startActivityForResult(intent, MANAGE_STORAGE_RC)
} catch (e: Exception) {
showErrorToast(e)
val intent = Intent()
intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
startActivityForResult(intent, MANAGE_STORAGE_RC)
}
} else {
finish()
}
}
} else {
handlePermission(PERMISSION_WRITE_STORAGE, callback)
}
}
}

private fun initFileManager(refreshRecents: Boolean) {
if (intent.action == Intent.ACTION_VIEW && intent.data != null) {
val data = intent.data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,21 @@ class SaveAsActivity : SimpleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
tryInitFileManager()
}

private fun tryInitFileManager() {
handleStoragePermission { granted ->
if (granted) {
saveAsDialog()
} else {
toast(R.string.no_storage_permissions)
finish()
}
}
}

private fun saveAsDialog() {
if (intent.action == Intent.ACTION_SEND && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true) {
FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden(), showFAB = true, showFavoritesButton = true) {
val destination = it
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package org.fossify.filemanager.activities

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Environment
import android.provider.Settings
import org.fossify.commons.activities.BaseSimpleActivity
import org.fossify.commons.dialogs.ConfirmationAdvancedDialog
import org.fossify.commons.extensions.hasPermission
import android.net.Uri
import org.fossify.commons.extensions.showErrorToast
import org.fossify.commons.extensions.toast
import org.fossify.commons.helpers.PERMISSION_WRITE_STORAGE
import org.fossify.commons.helpers.isRPlus
import org.fossify.filemanager.R
Expand Down Expand Up @@ -31,10 +37,23 @@ open class SimpleActivity : BaseSimpleActivity() {
R.mipmap.ic_launcher_grey_black
)

companion object {
private const val MANAGE_STORAGE_RC = 201
}

override fun getAppLauncherName() = getString(R.string.app_launcher_name)

override fun getRepositoryName() = "File-Manager"

@SuppressLint("NewApi")
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
isAskingPermissions = false
if (requestCode == MANAGE_STORAGE_RC && isRPlus()) {
actionOnPermission?.invoke(Environment.isExternalStorageManager())
}
}

@SuppressLint("NewApi")
fun hasStoragePermission(): Boolean {
return if (isRPlus()) {
Expand All @@ -43,4 +62,39 @@ open class SimpleActivity : BaseSimpleActivity() {
hasPermission(PERMISSION_WRITE_STORAGE)
}
}

@SuppressLint("InlinedApi")
fun handleStoragePermission(callback: (granted: Boolean) -> Unit) {
actionOnPermission = null
if (hasStoragePermission()) {
callback(true)
} else {
if (isRPlus()) {
ConfirmationAdvancedDialog(this, "", R.string.access_storage_prompt, R.string.ok, 0, false) { success ->
if (success) {
isAskingPermissions = true
actionOnPermission = callback
try {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.addCategory("android.intent.category.DEFAULT")
intent.data = Uri.parse("package:$packageName")
startActivityForResult(intent, MANAGE_STORAGE_RC)
} catch (e: android.content.ActivityNotFoundException) {
showErrorToast(e)
val intent = Intent()
intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
startActivityForResult(intent, MANAGE_STORAGE_RC)
} catch (e: SecurityException) {
showErrorToast(e)
finish()
}
} else {
finish()
}
}
} else {
handlePermission(PERMISSION_WRITE_STORAGE, callback)
}
}
}
}