Skip to content

Commit 15efccf

Browse files
author
Jan Guegel
committed
-fix detekt message by splitting up in two activities
-fix wildcard import in SaveAsActivity.kt
1 parent 56345f1 commit 15efccf

File tree

3 files changed

+204
-173
lines changed

3 files changed

+204
-173
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,18 @@
119119
android:label="@string/save_as">
120120
<intent-filter>
121121
<action android:name="android.intent.action.SEND" />
122+
<category android:name="android.intent.category.DEFAULT" />
123+
124+
<data android:mimeType="*/*" />
125+
</intent-filter>
126+
</activity>
127+
128+
<activity
129+
android:name=".activities.SaveAsMultipleActivity"
130+
android:configChanges="orientation"
131+
android:exported="true"
132+
android:label="@string/save_as">
133+
<intent-filter>
122134
<action android:name="android.intent.action.SEND_MULTIPLE" />
123135
<category android:name="android.intent.category.DEFAULT" />
124136

app/src/main/kotlin/org/fossify/filemanager/activities/SaveAsActivity.kt

Lines changed: 48 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,23 @@ import android.content.Intent
44
import android.net.Uri
55
import android.os.Bundle
66
import org.fossify.commons.dialogs.FilePickerDialog
7-
import org.fossify.commons.extensions.*
7+
import org.fossify.commons.extensions.getDocumentFile
8+
import org.fossify.commons.extensions.getDoesFilePathExist
9+
import org.fossify.commons.extensions.getFileOutputStreamSync
10+
import org.fossify.commons.extensions.getFilenameFromContentUri
11+
import org.fossify.commons.extensions.getFilenameFromPath
12+
import org.fossify.commons.extensions.getMimeType
13+
import org.fossify.commons.extensions.needsStupidWritePermissions
14+
import org.fossify.commons.extensions.rescanPaths
15+
import org.fossify.commons.extensions.showErrorToast
16+
import org.fossify.commons.extensions.toast
17+
import org.fossify.commons.extensions.viewBinding
818
import org.fossify.commons.helpers.NavigationIcon
919
import org.fossify.commons.helpers.ensureBackgroundThread
1020
import org.fossify.filemanager.R
1121
import org.fossify.filemanager.databinding.ActivitySaveAsBinding
1222
import org.fossify.filemanager.extensions.config
1323
import java.io.File
14-
import java.io.IOException
1524

1625
class SaveAsActivity : SimpleActivity() {
1726
private val binding by viewBinding(ActivitySaveAsBinding::inflate)
@@ -34,184 +43,50 @@ class SaveAsActivity : SimpleActivity() {
3443
}
3544

3645
private fun saveAsDialog() {
37-
when {
38-
intent.action == Intent.ACTION_SEND && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true -> {
39-
handleSingleFile()
40-
}
41-
intent.action == Intent.ACTION_SEND_MULTIPLE && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true -> {
42-
handleMultipleFiles()
43-
}
44-
else -> {
45-
toast(R.string.unknown_error_occurred)
46-
finish()
47-
}
48-
}
49-
}
50-
51-
private fun handleSingleFile() {
52-
FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden(), showFAB = true, showFavoritesButton = true) {
53-
val destination = it
54-
handleSAFDialog(destination) {
55-
toast(R.string.saving)
56-
ensureBackgroundThread {
57-
try {
58-
createDestinationIfNeeded(destination)
59-
60-
val source = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)!!
61-
val originalFilename = getFilenameFromContentUri(source)
62-
?: source.toString().getFilenameFromPath()
63-
val filename = sanitizeFilename(originalFilename)
64-
val mimeType = contentResolver.getType(source)
65-
?: intent.type?.takeIf { it != "*/*" }
66-
?: filename.getMimeType()
67-
val inputStream = contentResolver.openInputStream(source)
68-
69-
val destinationPath = getAvailablePath("$destination/$filename")
70-
val outputStream = getFileOutputStreamSync(destinationPath, mimeType, null)!!
71-
inputStream!!.copyTo(outputStream)
72-
rescanPaths(arrayListOf(destinationPath))
73-
toast(R.string.file_saved)
74-
finish()
75-
} catch (e: IOException) {
76-
showErrorToast(e)
77-
finish()
78-
} catch (e: SecurityException) {
79-
showErrorToast(e)
80-
finish()
46+
if (intent.action == Intent.ACTION_SEND && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true) {
47+
FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden(), showFAB = true, showFavoritesButton = true) {
48+
val destination = it
49+
handleSAFDialog(destination) {
50+
toast(R.string.saving)
51+
ensureBackgroundThread {
52+
try {
53+
if (!getDoesFilePathExist(destination)) {
54+
if (needsStupidWritePermissions(destination)) {
55+
val document = getDocumentFile(destination)
56+
document!!.createDirectory(destination.getFilenameFromPath())
57+
} else {
58+
File(destination).mkdirs()
59+
}
60+
}
61+
62+
val source = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)!!
63+
val originalFilename = getFilenameFromContentUri(source)
64+
?: source.toString().getFilenameFromPath()
65+
val filename = sanitizeFilename(originalFilename)
66+
val mimeType = contentResolver.getType(source)
67+
?: intent.type?.takeIf { it != "*/*" }
68+
?: filename.getMimeType()
69+
val inputStream = contentResolver.openInputStream(source)
70+
71+
val destinationPath = getAvailablePath("$destination/$filename")
72+
val outputStream = getFileOutputStreamSync(destinationPath, mimeType, null)!!
73+
inputStream!!.copyTo(outputStream)
74+
rescanPaths(arrayListOf(destinationPath))
75+
toast(R.string.file_saved)
76+
finish()
77+
} catch (e: Exception) {
78+
showErrorToast(e)
79+
finish()
80+
}
8181
}
8282
}
8383
}
84-
}
85-
}
86-
87-
private fun handleMultipleFiles() {
88-
FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden(), showFAB = true, showFavoritesButton = true) { destination ->
89-
handleSAFDialog(destination) {
90-
toast(R.string.saving)
91-
ensureBackgroundThread {
92-
processMultipleFiles(destination)
93-
}
94-
}
95-
}
96-
}
97-
98-
private fun processMultipleFiles(destination: String) {
99-
try {
100-
createDestinationIfNeeded(destination)
101-
102-
val uriList = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
103-
if (uriList.isNullOrEmpty()) {
104-
runOnUiThread {
105-
toast(R.string.no_items_found)
106-
finish()
107-
}
108-
return
109-
}
110-
111-
val result = saveAllFiles(destination, uriList)
112-
showFinalResult(result)
113-
} catch (e: IOException) {
114-
runOnUiThread {
115-
showErrorToast(e)
116-
finish()
117-
}
118-
} catch (e: SecurityException) {
119-
runOnUiThread {
120-
showErrorToast(e)
121-
finish()
122-
}
123-
}
124-
}
125-
126-
private fun saveAllFiles(destination: String, uriList: ArrayList<Uri>): SaveResult {
127-
val mimeTypes = intent.getStringArrayListExtra(Intent.EXTRA_MIME_TYPES)
128-
val savedPaths = mutableListOf<String>()
129-
var successCount = 0
130-
var errorCount = 0
131-
132-
for ((index, source) in uriList.withIndex()) {
133-
if (saveSingleFileItem(destination, source, index, mimeTypes)) {
134-
successCount++
135-
savedPaths.add(destination)
136-
} else {
137-
errorCount++
138-
}
139-
}
140-
141-
if (savedPaths.isNotEmpty()) {
142-
rescanPaths(ArrayList(savedPaths))
143-
}
144-
145-
return SaveResult(successCount, errorCount)
146-
}
147-
148-
private fun saveSingleFileItem(
149-
destination: String,
150-
source: Uri,
151-
index: Int,
152-
mimeTypes: ArrayList<String>?): Boolean {
153-
return try {
154-
val originalFilename = getFilenameFromContentUri(source)
155-
?: source.toString().getFilenameFromPath()
156-
val filename = sanitizeFilename(originalFilename)
157-
158-
val mimeType = contentResolver.getType(source)
159-
?: mimeTypes?.getOrNull(index)?.takeIf { it != "*/*" }
160-
?: intent.type?.takeIf { it != "*/*" }
161-
?: filename.getMimeType()
162-
163-
val inputStream = contentResolver.openInputStream(source)
164-
?: throw IOException(getString(R.string.error, source))
165-
166-
val destinationPath = getAvailablePath("$destination/$filename")
167-
val outputStream = getFileOutputStreamSync(destinationPath, mimeType, null)
168-
?: throw IOException(getString(R.string.error, source))
169-
170-
inputStream.use { input ->
171-
outputStream.use { output ->
172-
input.copyTo(output)
173-
}
174-
}
175-
true
176-
} catch (e: IOException) {
177-
showErrorToast(e)
178-
false
179-
} catch (e: SecurityException) {
180-
showErrorToast(e)
181-
false
182-
}
183-
}
184-
185-
private fun showFinalResult(result: SaveResult) {
186-
runOnUiThread {
187-
when {
188-
result.successCount > 0 && result.errorCount == 0 -> {
189-
val message = resources.getQuantityString(R.plurals.files_saved,result.successCount)
190-
toast(message)
191-
}
192-
result.successCount > 0 && result.errorCount > 0 -> {
193-
toast(getString(R.string.files_saved_partially))
194-
}
195-
else -> {
196-
toast(R.string.error)
197-
}
198-
}
84+
} else {
85+
toast(R.string.unknown_error_occurred)
19986
finish()
20087
}
20188
}
20289

203-
private data class SaveResult(val successCount: Int, val errorCount: Int)
204-
private fun createDestinationIfNeeded(destination: String) {
205-
if (!getDoesFilePathExist(destination)) {
206-
if (needsStupidWritePermissions(destination)) {
207-
val document = getDocumentFile(destination)
208-
document!!.createDirectory(destination.getFilenameFromPath())
209-
} else {
210-
File(destination).mkdirs()
211-
}
212-
}
213-
}
214-
21590
override fun onResume() {
21691
super.onResume()
21792
setupTopAppBar(binding.activitySaveAsAppbar, NavigationIcon.Arrow)

0 commit comments

Comments
 (0)