Abrir archivo en el directorio de caché con ACTION_VIEW

He estado buscando esto por un tiempo ahora pero no puedo hacer que esto funcione correctamente. Dejame explicar.

Tengo una aplicación de Android que guarda archivos (imágenes, documentos, …) en el directorio de caché. Al principio usaba el método getExternalCacheDir() y los getExternalCacheDir() allí, pero porque debería estar en caché en dispositivos que no tienen una tarjeta SD, tengo que usar getCacheDir() .

Cuando usaba el método getExternalCacheDir() , no era ningún problema abrir esos archivos en otra aplicación como esta:

 Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), mimetype); 

Pero al utilizar getCacheDir() , esos archivos se guardan en el entorno limitado de la aplicación y no son accesibles desde fuera de la aplicación. Así que googled y llegó en el ** ContentProvider . Un ContentProvider hace posible abrir archivos privados con aplicaciones externas. Pero cuando intento implementarlo, no funciona.

Intenté implementar el ContentProvider gracias a esta publicación: ¿Cómo abrir archivos privados guardados en el almacenamiento interno mediante Intent.ACTION_VIEW? Pero sin éxito.

 package com.myapplication.providers; import java.io.File; import java.io.FileNotFoundException; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; public class FileProvider extends ContentProvider { @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { File privateFile = new File(getContext().getCacheDir(), uri.getPath()); return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY); } @Override public int delete(Uri arg0, String arg1, String[] arg2) { return 0; } @Override public String getType(Uri arg0) { return null; } @Override public Uri insert(Uri arg0, ContentValues arg1) { return null; } @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { return null; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { return 0; } } 

Se agregó este proveedor al manifiesto de aplicación.

 <provider android:name="com.myapplication.providers.FileProvider" android:authorities="com.myapplication" android:exported="true" /> 

Y utilizando este código para abrir el archivo:

 Uri uri = Uri.parse("content://com.myapplication/" + filename); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(uri, mimetype); 

¡Gracias por adelantado!

Descubrí que tenía que hacer las cosas de manera diferente.

En lugar de crear mi propio ContentProvider, la biblioteca de soporte v4 ofrece una clase FileProvider que se puede utilizar.

En AndroidManifest.xml agregar

 <application ...> <provider android:name="android.support.v4.content.FileProvider" android:authorities="be.myapplication" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> 

FILE_PROVIDER_PATHS es un archivo xml que describe qué archivos pueden ser leídos por otras aplicaciones.

Así que agregué un archivo file_paths.xml a la carpeta res / xml.

 <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="my_cache" path="." /> </paths> 

Y lo único que tienes que hacer entonces es crear e iniciar la intención de mostrar el archivo.

 File file = new File(getCacheDir(), "test.pdf"); Uri uri = FileProvider.getUriForFile(context, "be.myapplication", file); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(uri, "application/pdf"); startActivity(intent); 

Y en realidad eso es todo.

IMPORTANTE : No olvide establecer los indicadores FLAG_GRANT_READ_URI_PERMISSION para la intención. De lo contrario, no funcionará.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.