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:
darthpaul 2022-03-15 22:47:54 +00:00
parent 6b046b38f7
commit 63d685d61a
4 changed files with 59 additions and 3 deletions

View file

@ -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 {

View file

@ -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) {

View file

@ -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)
}

View file

@ -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"