sdk 30 changes
- handle creating new folder in the root of internal or SD card storage - use ACTION_CREATE_DOCUMENT intent to with SAF to give the user opportunity to save the desired folder
This commit is contained in:
parent
6b046b38f7
commit
63d685d61a
4 changed files with 59 additions and 3 deletions
|
@ -223,8 +223,27 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
val sdOtgPattern = Pattern.compile(SD_OTG_SHORT)
|
||||
if (requestCode == CREATE_DOCUMENT_SDK_30) {
|
||||
if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
|
||||
|
||||
if (requestCode == OPEN_DOCUMENT_TREE_FOR_SDK_30) {
|
||||
val treeUri = resultData.data
|
||||
val checkedUri = buildDocumentUriSdk30(checkedDocumentPath)
|
||||
|
||||
if (treeUri != checkedUri) {
|
||||
toast(getString(R.string.wrong_folder_selected, checkedDocumentPath))
|
||||
return
|
||||
}
|
||||
|
||||
val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
applicationContext.contentResolver.takePersistableUriPermission(treeUri, takeFlags)
|
||||
val funAfter = funAfterDelete30File
|
||||
funAfterDelete30File = null
|
||||
funAfter?.invoke(true)
|
||||
} else {
|
||||
funAfterDelete30File?.invoke(false)
|
||||
}
|
||||
|
||||
} else if (requestCode == OPEN_DOCUMENT_TREE_FOR_SDK_30) {
|
||||
if (resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
|
||||
|
||||
val treeUri = resultData.data
|
||||
|
@ -430,7 +449,20 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
|
|||
return if (!packageName.startsWith("com.simplemobiletools")) {
|
||||
callback(true)
|
||||
false
|
||||
} else if (isShowingSAFDialogForDeleteSdk30(path)) {
|
||||
} else if (isShowingSAFDialogSdk30(path)) {
|
||||
funAfterDelete30File = callback
|
||||
true
|
||||
} else {
|
||||
callback(true)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun handleSAFCreateDocumentDialogSdk30(path: String, callback: (success: Boolean) -> Unit): Boolean {
|
||||
return if (!packageName.startsWith("com.simplemobiletools")) {
|
||||
callback(true)
|
||||
false
|
||||
} else if (isShowingSAFCreateDocumentDialogSdk30(path)) {
|
||||
funAfterDelete30File = callback
|
||||
true
|
||||
} else {
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.appcompat.app.AlertDialog
|
|||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.isRPlus
|
||||
import kotlinx.android.synthetic.main.dialog_create_new_folder.view.*
|
||||
import java.io.File
|
||||
|
||||
|
@ -43,7 +44,7 @@ class CreateNewFolderDialog(val activity: BaseSimpleActivity, val path: String,
|
|||
try {
|
||||
when {
|
||||
activity.isRestrictedSAFOnlyRoot(path) && activity.createAndroidSAFDirectory(path) -> sendSuccess(alertDialog, path)
|
||||
activity.isAccessibleWithSAFSdk30(path) -> activity.handleSAFDialogSdk30(path){
|
||||
activity.isAccessibleWithSAFSdk30(path) -> activity.handleSAFDialogSdk30(path) {
|
||||
if (it && activity.createSAFDirectorySdk30(path)) {
|
||||
sendSuccess(alertDialog, path)
|
||||
}
|
||||
|
@ -64,6 +65,11 @@ class CreateNewFolderDialog(val activity: BaseSimpleActivity, val path: String,
|
|||
}
|
||||
}
|
||||
File(path).mkdirs() -> sendSuccess(alertDialog, path)
|
||||
isRPlus() && path.getParentPath().isBasePath(activity) -> activity.handleSAFCreateDocumentDialogSdk30(path) {
|
||||
if (it) {
|
||||
sendSuccess(alertDialog, path)
|
||||
}
|
||||
}
|
||||
else -> activity.toast(activity.getString(R.string.could_not_create_folder, path.getFilenameFromPath()))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -152,3 +152,20 @@ fun Context.deleteDocumentWithSAFSdk30(fileDirItem: FileDirItem, allowDeleteFold
|
|||
showErrorToast(e)
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.hasProperStoredDocumentUriSdk30(path: String): Boolean {
|
||||
val documentUri = buildDocumentUriSdk30(path)
|
||||
return contentResolver.persistedUriPermissions.any { it.uri.toString() == documentUri.toString() }
|
||||
}
|
||||
|
||||
fun Context.buildDocumentUriSdk30(fullPath: String): Uri {
|
||||
val storageId = getSAFStorageId(fullPath)
|
||||
|
||||
val relativePath = when {
|
||||
fullPath.startsWith(internalStoragePath) -> fullPath.substring(internalStoragePath.length).trim('/')
|
||||
else -> fullPath.substringAfter(storageId).trim('/')
|
||||
}
|
||||
|
||||
val documentId = "${storageId}:$relativePath"
|
||||
return DocumentsContract.buildDocumentUri(EXTERNAL_STORAGE_PROVIDER_AUTHORITY, documentId)
|
||||
}
|
||||
|
|
|
@ -203,6 +203,7 @@ const val REQUEST_SET_AS = 1004
|
|||
const val REQUEST_EDIT_IMAGE = 1005
|
||||
const val SELECT_EXPORT_SETTINGS_FILE_INTENT = 1006
|
||||
const val REQUEST_CODE_SET_DEFAULT_DIALER = 1007
|
||||
const val CREATE_DOCUMENT_SDK_30 = 1008
|
||||
|
||||
// sorting
|
||||
const val SORT_ORDER = "sort_order"
|
||||
|
|
Loading…
Reference in a new issue