Не удается прочитать файл - FileNotFoundException - Android 11, составить, ActivityResultContracts, READ_EXTERNAL_STORAGE
Я пытаюсь прочитать файл с внешнего хранилища
/some/path/somefile.txt
В манифесте у меня есть
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Когда я нажимаю кнопку, чтобы попытаться прочитать файл, выбранный
ActivityResultContracts.OpenDocument()
я получаю
java.io.FileNotFoundException: /document/primary:some/path/somefile.txt: open failed: ENOENT (No such file or directory)
Вот мой код:
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun ReadFileScreen() {
val readPermissionState = rememberPermissionState(
android.Manifest.permission.READ_EXTERNAL_STORAGE
)
val pickedFileUriState = remember { mutableStateOf<Uri?>(null) }
val launcher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.OpenDocument()) { result ->
pickedFileUriState.value = result
}
Column {
Button(onClick = readPermissionState::launchPermissionRequest) {
Text("request read permission")
}
PermissionRequired(readPermissionState, {}, {}) {
Button(onClick = { launcher.launch(arrayOf("*/*")) }
) {
Text("pick file")
}
if (pickedFileUriState.value != null) Button(onClick = { readTextFile(pickedFileUriState.value!!) }
) {
Text("read file")
}
}
}
}
fun readTextFile(uri: Uri) {
try {
val text = File(uri.path).readText()
println(text)
} catch (e: Exception) {
e.printStackTrace()
}
}
1 ответ
Благодаря @ianhanniballake ссылка научила меня, как правильно получить доступ к файлу, выбранному пользователем.
Вот код, который я придумал:
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun ReadFileScreen() {
val context = LocalContext.current
val pickedFileUriState = remember { mutableStateOf<Uri?>(null) }
val launcher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.OpenDocument()) { result ->
pickedFileUriState.value = result
}
Column {
Button(onClick = { launcher.launch(arrayOf("*/*")) }
) {
Text("pick file")
}
if (pickedFileUriState.value != null)
Button(onClick = {
readTextFromUri(context, pickedFileUriState.value!!)
}
) {
Text("read file")
}
}
}
private fun readTextFromUri(context: Context, uri: Uri) {
try {
val stringBuilder = StringBuilder()
context.contentResolver.openInputStream(uri)?.use { inputStream ->
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String? = reader.readLine()
while (line != null) {
stringBuilder.append(line)
line = reader.readLine()
}
}
}
val text = stringBuilder.toString()
Log.d("xxx", "text $text")
} catch (e: IOException) {
e.printStackTrace()
}
}