Fix Xiaomi picker crash on non-persistable content Uri
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package io.legado.app.ui.config.otherConfig
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
@@ -43,6 +42,7 @@ import io.legado.app.ui.widget.components.settingItem.InputSettingItem
|
||||
import io.legado.app.ui.widget.components.settingItem.SliderSettingItem
|
||||
import io.legado.app.ui.widget.components.settingItem.SwitchSettingItem
|
||||
import io.legado.app.utils.restart
|
||||
import io.legado.app.utils.takePersistablePermissionSafely
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -75,9 +75,7 @@ fun OtherConfigScreen(
|
||||
contract = ActivityResultContracts.OpenDocumentTree()
|
||||
) { uri ->
|
||||
uri?.let {
|
||||
val modeFlags =
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
context.contentResolver.takePersistableUriPermission(it, modeFlags)
|
||||
it.takePersistablePermissionSafely(context)
|
||||
viewModel.updateLocalBookDir(it.toString())
|
||||
}
|
||||
}
|
||||
@@ -509,4 +507,4 @@ fun ConfirmDialog(
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.legado.app.utils.externalFiles
|
||||
import io.legado.app.utils.getJsonArray
|
||||
import io.legado.app.utils.isContentScheme
|
||||
import io.legado.app.utils.launch
|
||||
import io.legado.app.utils.takePersistablePermissionSafely
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import splitties.init.appCtx
|
||||
@@ -40,9 +41,7 @@ class HandleFileActivity :
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
|
||||
uri?.let {
|
||||
if (uri.isContentScheme()) {
|
||||
val modeFlags =
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
contentResolver.takePersistableUriPermission(uri, modeFlags)
|
||||
uri.takePersistablePermissionSafely(this)
|
||||
}
|
||||
onResult(Intent().setData(uri))
|
||||
} ?: finish()
|
||||
@@ -51,9 +50,7 @@ class HandleFileActivity :
|
||||
private val selectDoc = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
|
||||
it?.let {
|
||||
if (it.isContentScheme()) {
|
||||
val modeFlags =
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
contentResolver.takePersistableUriPermission(it, modeFlags)
|
||||
it.takePersistablePermissionSafely(this)
|
||||
}
|
||||
onResult(Intent().setData(it))
|
||||
} ?: finish()
|
||||
@@ -307,4 +304,4 @@ class HandleFileActivity :
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,43 @@ fun Uri.isContentScheme() = this.scheme == "content"
|
||||
|
||||
fun Uri.isFileScheme() = this.scheme == "file"
|
||||
|
||||
/**
|
||||
* Some vendors return non-persistable content Uris even in system picker flows.
|
||||
* Try to persist read/write grants separately and never throw.
|
||||
*/
|
||||
fun Uri.takePersistablePermissionSafely(
|
||||
context: Context,
|
||||
modeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
): Boolean {
|
||||
if (!isContentScheme()) return false
|
||||
var granted = false
|
||||
if (modeFlags and Intent.FLAG_GRANT_READ_URI_PERMISSION != 0) {
|
||||
kotlin.runCatching {
|
||||
context.contentResolver.takePersistableUriPermission(
|
||||
this,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
}.onSuccess {
|
||||
granted = true
|
||||
}.onFailure {
|
||||
AppLog.put("持久化读取权限失败: $this", it)
|
||||
}
|
||||
}
|
||||
if (modeFlags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION != 0) {
|
||||
kotlin.runCatching {
|
||||
context.contentResolver.takePersistableUriPermission(
|
||||
this,
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
)
|
||||
}.onSuccess {
|
||||
granted = true
|
||||
}.onFailure {
|
||||
AppLog.put("持久化写入权限失败: $this", it)
|
||||
}
|
||||
}
|
||||
return granted
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取URI
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user