0

我正在尝试从外部存储中读取文件/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()
  }
}
4

1 回答 1

0

感谢@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()
  }
}
于 2021-10-22T05:18:45.133 回答