Android SAF (Storage Access FrameWork): Obtenga un archivo Uri de TreeUri
Estoy tomando PersistableUriPermission de la tarjeta Sd externa y lo guardo para uso posterior. Ahora quiero que cuando el usuario me proporciona la ruta del archivo, de la lista de archivos en mi aplicación, quiero editar el documento y cambiar el nombre.
Así que tengo la ruta del archivo del archivo para editar.
- ¿Cómo agregar un archivo a un proyecto de Android, desplegarlo en el dispositivo y abrirlo?
- ¿Cómo comprobar si dos caminos están en el mismo punto de montaje?
- Android: ¿Cómo almacenar datos en la memoria interna?
- Eliminación del contenido del archivo android
- Error de permiso de escritura de archivo en Android
Mi pregunta es cómo puedo obtener Uri de ese archivo desde mi TreeUri para editar el archivo.
- Permiso denegado al crear nuevo archivo en almacenamiento externo
- Editar mediante programación las propiedades de build.prop en Android
- Eliminar archivos anteriores al tiempo dado desde el directorio
- File.list () devuelve null para directorio
- Cómo leer el archivo de res / raw por nombre
- Cómo mostrar el tamaño del archivo en vista de lista con nombre de archivo
- Protege y desprotege el archivo para evitar la eliminación accidental en Android mediante aplicaciones de limpieza con errores
- Android: Diferencia entre FileOutputStream y FileWriter
Acceso a los archivos de Sd-Card
Utilice el diálogo DOCUMENT_TREE
para obtener el Uri
la tarjeta SD.
Informar al usuario sobre cómo elegir sd-card
en el diálogo. (Con imágenes o animaciones gif)
// call for document tree dialog Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
En onActivityResult
tendrá el directorio seleccionado Uri
. (SdCardUri)
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_CODE_OPEN_DOCUMENT_TREE: if (resultCode == Activity.RESULT_OK) { sdCardUri = data.getData(); } beak; } }
Ahora debe comprobar si el usuario,
a. Seleccionó la tarjeta sd
segundo. Seleccionó la tarjeta SD en la que se encuentra nuestro archivo (algunos dispositivos podrían tener varias tarjetas SD).
Comprobamos tanto a como b encontrando el archivo a través de la jerarquía, desde la raíz sd a nuestro archivo. Si se encuentra el archivo, se obtienen las condiciones a y b.
//First we get `DocumentFile` from the `TreeUri` which in our case is `sdCardUri`. DocumentFile documentFile = DocumentFile.fromTreeUri(this, sdCardUri); //Then we split file path into array of strings. //ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "myImage.jpg"} // There is a reason for having two similar names "MyFolder" in //my exmple file path to show you similarity in names in a path will not //distract our hiarchy search that is provided below. String[] parts = (file.getPath()).split("\\/"); // findFile method will search documentFile for the first file // with the expected `DisplayName` // We skip first three items because we are already on it.(sdCardUri = /storage/extSdCard) for (int i = 3; i < parts.length; i++) { if (documentFile != null) { documentFile = documentFile.findFile(parts[i]); } } if (documentFile == null) { // File not found on tree search // User selected a wrong directory as the sd-card // Here must inform user about how to get the correct sd-card // and invoke file chooser dialog again. } else { // File found on sd-card and it is a correct sd-card directory // save this path as a root for sd-card on your database(SQLite, XML, txt,...) // Now do whatever you like to do with documentFile. // Here I do deletion to provide an example. if (documentFile.delete()) {// if delete file succeed // Remove information related to your media from ContentResolver, // which documentFile.delete() didn't do the trick for me. // Must do it otherwise you will end up with showing an empty // ImageView if you are getting your URLs from MediaStore. // Uri mediaContentUri = ContentUris.withAppendedId( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, longMediaId); getContentResolver().delete(mediaContentUri , null, null); } }
Nota:
Debe proporcionar permiso de acceso al almacenamiento externo dentro de su manifiesto y para os> = Marshmallow dentro de la aplicación. https://stackoverflow.com/a/32175771/2123400
Editar archivos de Sd-Card
Para editar una imagen existente en su tarjeta SD, no necesita ninguno de los pasos anteriores si desea invocar otra aplicación para que lo haga por usted.
Aquí invocamos todas las actividades (desde todas las aplicaciones instaladas) con la capacidad de editar las imágenes. (Los programadores marcan sus aplicaciones en el manifiesto por sus capacidades para proporcionar accesibilidad desde otras aplicaciones (actividades)).
En su editButton haga clic en evento:
String mimeType = getMimeTypeFromMediaContentUri(mediaContentUri); startActivityForResult(Intent.createChooser(new Intent(Intent.ACTION_EDIT).setDataAndType(mediaContentUri, mimeType).putExtra(Intent.EXTRA_STREAM, mediaContentUri).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION), "Edit"), REQUEST_CODE_SHARE_EDIT_SET_AS_INTENT);
Y esta es la forma de obtener mimeType:
public String getMimeTypeFromMediaContentUri(Uri uri) { String mimeType; if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { ContentResolver cr = getContentResolver(); mimeType = cr.getType(uri); } else { String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri .toString()); mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension( fileExtension.toLowerCase()); } return mimeType; }
Nota:
En kitkat (4.4) no le pedirá que seleccione la tarjeta sd, porque en esta versión de android DocumentProvider
no es aplicable, por lo tanto no tenemos ninguna posibilidad de tener acceso a la tarjeta sd. Mire el nivel de api para el DocumentProvider
https://developer.android.com/reference/android/provider/DocumentsProvider.html
En versiones por debajo del kitkat, el acceso a la tarjeta sd ya está proporcionado por el sistema operativo.
- Vincular la vista personalizada de Android a una xml de diseño específico (¿es posible?)
- RecyclerView y DiffUtil – Una pesadilla de concurrencia