Android: ¿cómo adjunto una imagen generada temporal a un correo electrónico?

Tengo una imagen generada mediante progtwigción que deseo enviar como archivo adjunto a través del método ACTION_SEND y EXTRA_STREAM .

¿Pero cómo hago esto?

Mi primer bash (escribir en mi ruta de archivo basada en context.getCacheDir() ) parecía funcionar en la vista previa de Gmail (sin vista previa de imágenes, pero el nombre del archivo adjunto y el ícono estaban visibles), pero el archivo adjunto nunca llegó al destinatario. Supongo que esto tiene algo que ver con los permisos en el archivo generado, pero ¿cómo evitar esto? ¿Debo establecer una configuración más permisiva en estos archivos generados (para que la actividad de Gmail pueda acceder)? ¿Es eso posible para la carpeta de caché de la aplicación?

¿Hay otra ubicación de archivo que sea más adecuada para escribir mis archivos? Consideré la carpeta de descargas, pero creo que sería una ubicación incómoda para algo que solo debe existir hasta que se haya enviado por correo electrónico.

Incluso he intentado codificar mi imagen puramente en un URI de data:image/png;base64,ABCD... style. Esto también apareció en la vista previa de Gmail (icono del archivo adjunto, pero no en el nombre del archivo), pero no dio como resultado un archivo adjunto del destinatario.

¿Alguien ha podido adjuntar una imagen generada de una sola vez a un bash de correo electrónico de ninguna manera? ¿Qué opciones puedo haber pasado por alto?

Mi problema realmente consistía en dos partes:

  1. context.getCacheDir() es privado para su aplicación. No puede poner algo ahí y esperar que otra aplicación pueda acceder a él.
  2. No entendí qué tipo de MIME debería haber estado usando. Aunque estaba enviando un mensaje de correo electrónico, realmente necesitaba especificar image/png por el bien de mis archivos adjuntos.

Además, la investigación indicó que poner imágenes (potencialmente grandes) en la memoria primaria no era una buena idea, incluso si lo limpiaba de inmediato.

Una vez que hice estas cosas y escribí mis imágenes generadas en una ubicación pública en la tarjeta SD, funcionó bien.

Entonces, en resumen:

Solicite acceso a la tarjeta SD en su manifiesto

  

Asegúrate de que la tarjeta SD esté disponible

 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { //Bail gracefully } 

Crea un directorio en la tarjeta SD

 File pngDir = new File( Environment.getExternalStorageDirectory(), //Loose convention inferred from app examples "Android/data/com.somedomain.someapp/flotsam"); if (!pngDir.exists()) pngDir.mkdirs(); 

Escribe tu archivo en ese directorio y captura el Uri

 File pngFile = new File(pngDir, "jetsam.png"); //Save file encoded as PNG Uri pngUri = Uri.fromFile(pngFile); 

Crea un bash ACTION_SEND

 Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("image/png"); // intent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "someone@somewhere.com" }); intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Portable Network Graphics"); intent.putExtra(android.content.Intent.EXTRA_CC, new String[] { "carbon@somewhere.com" }); intent.putExtra(Intent.EXTRA_TEXT, "Something textual"); intent.putExtra(Intent.EXTRA_STREAM, pngUri); 

Y luego comienza la actividad

 context.startActivity(Intent.createChooser(intent, "Something Pithy")); 

Y luego asegúrate de limpiar todo …

Advertencia 1

Parece que hay más soporte para directorios de tarjetas SD específicos de la aplicación, pero desafortunadamente, no en mi versión SDK requerida.

Advertencia 2

Esta es una descripción general de la solución que finalmente funcionó para mí. No es necesariamente un enfoque de “mejores prácticas”.

Advertencia 3

Esto significa que la aplicación debe tener una tarjeta SD montada para tener la función de archivos adjuntos de imagen disponible, pero esto fue totalmente aceptable para mi caso de uso. Su experiencia puede ser diferente. Si la tarjeta SD no está disponible, añado una nota amistosa al correo electrónico explicando por qué no se podían adjuntar las imágenes y cómo rectificar la situación.

Me acabo de encontrar exactamente con el mismo problema (querer adjuntar un archivo de texto en mi caso). Si miras en el registro de Android, el motivo es:

 02-28 21:01:28.434: E/Gmail(19673): file:// attachment paths must point to file:///mnt/sdcard. Ignoring attachment file:///data/data/com.stephendnicholas.gmailattach/cache/Test.txt 

Como solución alternativa (mencionada por HRJ), puede usar ContentProvider para proporcionar acceso a los archivos en la memoria caché interna de la aplicación para que Gmail pueda adjuntarlos. Acabo de escribir una publicación de blog sobre cómo hacerlo.

Espero que sea de alguna ayuda 🙂

 tableLayout.buildDrawingCache(); Bitmap test = Bitmap.createBitmap(tableLayout.getDrawingCache()); tableLayout.destroyDrawingCache(); Log.d("Image", test.toString()); String path = Environment.getExternalStorageDirectory().toString(); Log.d("Path", path); File file = new File(path,"mail_image.png"); Uri pngUri = Uri.fromFile(file); Log.d("Real Image Path", pngUri.toString()); Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); emailIntent.setType("image/png"); emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "email to"); emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject"); emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "From My App"); emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, pngUri ); startActivity(Intent.createChooser(emailIntent, "Send mail..."));