Android: obtenga la ruta real de un archivo .txt seleccionado del explorador de archivos

Estoy trabajando en una aplicación en la que deseo poder exportar e importar algunos datos desde la aplicación, en un archivo .txt. La API mínima de la aplicación es 21.

La parte de exportación funciona bien, pero estoy teniendo problemas con la parte de importación.

Abro el explorador de archivos:

butImportPatient.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_OPEN_DOCUMENT); intent.setType("*/*"); startActivityForResult(intent, IMPORTPATIENT_ACTIVITY_REQUEST_CODE); } }); 

Parece que está funcionando.

Pero mi onActivityResult no funciona, no encontré cómo puedo obtener el archivo del Uri.

Por ahora, aquí está mi código:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == IMPORTPATIENT_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) { File file = new File(data.getData().getPath()) ; String path = file.getAbsolutePath() ; StringBuilder text = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(path)); String line; while ((line = br.readLine()) != null) { text.append(line); text.append("\n"); } br.close(); } catch (IOException e) { e.printStackTrace(); } AlertDialog.Builder builder = new AlertDialog.Builder(this) ; builder.setMessage(path) .show() ; } } 

Es una mezcla de varias publicaciones que vi aquí, pero ninguna parece funcionar.

Obtengo este camino:

 /document/home:List.txt 

Crea FileNotFoundException. ¿Cómo puedo obtener la ruta real del archivo?

No encontré cómo puedo obtener el archivo del Uri.

No hay archivo ACTION_OPEN_DOCUMENT y ACTION_GET_CONTENT no abren un archivo. Ellos abren un documento. Ese documento podría ser un archivo. Puede que no. Ese Uri podría señalar:

  • Un archivo local en almacenamiento externo
  • Un archivo local en el almacenamiento interno para la otra aplicación
  • Un archivo local en almacenamiento extraíble
  • Un archivo local que está encriptado y necesita ser descifrado sobre la marcha
  • Una secuencia de bytes en una columna BLOB en una base de datos
  • Un contenido que necesita ser descargado por la otra aplicación primero
  • …y así

¿Cómo puedo obtener la ruta real del archivo?

Tu no

Si solo desea aceptar archivos, integre una biblioteca de selección de archivos en lugar de usar ACTION_OPEN_DOCUMENT o ACTION_GET_CONTENT .

Si usa ACTION_GET_CONTENT , y el esquema del Uri que obtiene es file , entonces getPath() será una ruta del sistema de archivos.

De lo contrario, debe comprender que no tiene idea de dónde proviene el documento y dejar de pensar en términos de “ruta real del archivo”. Utilice ContentResolver y openInputStream() o DocumentFile.fromSingleUri() o técnicas similares para trabajar con Uri .