Solución:
No recibió una ruta de archivo, recibió una Uri
. Tienes que usar Uri
API basadas como ContentResolver.openInputStream()
para acceder a los contenidos en ese Uri
ya que Android no otorga su aplicación directamente File
acceso al archivo subyacente (también podría transmitirse desde Google Drive o descargarse directamente de Internet sin que su aplicación sepa que esto está sucediendo):
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Selected a file to load
if ((requestCode == 111) && (resultCode == RESULT_OK)) {
val selectedFilename = data?.data //The uri with the location of the file
if (selectedFilename != null) {
contentResolver.openInputStream(selectedFilename)?.bufferedReader()?.forEachLine {
val toast = Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT)
toast.show()
}
} else {
val msg = "Null filename data received!"
val toast = Toast.makeText(applicationContext, msg, Toast.LENGTH_LONG)
toast.show()
}
}
}
Aquí podemos asumir que obtenemos contenido del formato adecuado al pasar el tipo de mime adecuado a nuestra solicitud (ya que no es necesario que un archivo de texto termine exactamente en el .txt
extensión como parte de su camino):
val intent = Intent()
.setType("text/*")
.setAction(Intent.ACTION_GET_CONTENT)
startActivityForResult(Intent.createChooser(intent, "Select a file"), 111)
Lo que hará que cualquier archivo que no sea de texto no pueda seleccionarse automáticamente.
No puede abrir un archivo Java en un ÙRI
convertido a una cadena, la sección “ruta” del URI no tiene relación con la ubicación de un archivo físico.
Utilizar una contentResolver
para obtener un Java FileDescriptor
para abrir el archivo.
val parcelFileDescriptor: ParcelFileDescriptor =
contentResolver.openFileDescriptor(uri, "r")
val fileDescriptor: FileDescriptor = parcelFileDescriptor.fileDescriptor
Este método es compatible con Android 10, donde las rutas de archivo de los directorios privados que no son de la aplicación no se pueden utilizar.
https://developer.android.com/training/data-storage/shared/documents-files
Si obtiene “msf: xxx” en URI, use la siguiente solución donde he creado un archivo temporal en el directorio de caché de la aplicación y eliminé el mismo archivo después de completar mi tarea:
if (id != null && id.startsWith("msf:")) {
final File file = new File(mContext.getCacheDir(), Constant.TEMP_FILE + Objects.requireNonNull(mContext.getContentResolver().getType(imageUri)).split("https://foroayuda.es/")[1]);
try (final InputStream inputStream = mContext.getContentResolver().openInputStream(imageUri); OutputStream output = new FileOutputStream(file)) {
final byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
return file;
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
He solucionado este problema y funciona al 100% para msf. 🙂
También elimine el archivo temporal después de completar su trabajo:
private void deleteTempFile() {
final File[] files = requireContext().getCacheDir().listFiles();
if (files != null) {
for (final File file : files) {
if (file.getName().contains(Constant.TEMP_FILE)) {
file.delete();
}
}
}
}
Aquí el valor de TEMP_FILE es “temp”.