- ACTION_SEND actually can only handle one image attachment.
- The images were saved in the "private" app directory (the one you get when you call getFilesDir()) , which is problematic when attaching images to emails this way.
- There are not many clients that respond to ACTION_SEND which can accommodate text/html content and an attachment, let alone multiple attachments
- I used the ACTION_SEND_MULTIPLE intent, in order to send multiple attachments.
- I made temporary copies of the images in external storage before attaching them to the intent.
- I made sure only Gmail would be launched, since it is the only app I found which can reliably handle sending text/html and multiple image attachments.
1. Here's my code to create the Intent with a subject and a message:
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("text/html");
String subject = "email subject here";
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
String body = "<html><body>Here's some <b>HTML</b>content";
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, Html.fromHtml(body));emailIntent.setType("text/html");
String subject = "email subject here";
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
String body = "<html><body>Here's some <b>HTML</b>content";
2. Next, I add some code that loops through the filenames of the images I want to send, copies them to external storage, then attaches them to the intent:
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ArrayList<Uri> uris = new ArrayList<Uri>();
for (String fileName : imageFileNames)
{
String tempFilename = copyPhoto(fileName); //get a temp filename from the copy method
tempFileNames.add(tempFilename); //stored so i can delete the temp files after the send
File myFile = new File(Environment.getExternalStorageDirectory(),tempFilename);
Uri fileUri = Uri.fromFile(myFile);
uris.add(fileUri);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
ArrayList<Uri> uris = new ArrayList<Uri>();
for (String fileName : imageFileNames)
{
String tempFilename = copyPhoto(fileName); //get a temp filename from the copy method
tempFileNames.add(tempFilename); //stored so i can delete the temp files after the send
File myFile = new File(Environment.getExternalStorageDirectory(),tempFilename);
Uri fileUri = Uri.fromFile(myFile);
uris.add(fileUri);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
3. Now, some code to limit the app list to Gmail only:
final PackageManager pm = getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
ResolveInfo best = null;
for (final ResolveInfo info : matches)
if (info.activityInfo.packageName.endsWith(".gm") ||
info.activityInfo.name.toLowerCase().contains("gmail")) best = info;
if (best != null)
emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name);
And finally, we start the activity:
startActivityForResult(ACTION_SEND_WITH_IMAGES);
And there's that. I hope it helps :) Please join in with your comments...
What did you do about deleting the temporary file copies afterwards? One problem you will run into is that you don't have any idea when the email actually is finished being sent (for example, internet access may not be available until an hour later). Therefore, you need to decide whether to:
ReplyDelete1) Just leave the files lying around wasting space.
or
2) Delete the files at some point, risking the chance that the email has not yet been sent.
Excellent question. I stored all the temp filenames (above in the tempFileNames array), and then called another method called resetTempFiles() to delete them when the app was terminating. I also called a method on app launch to cleanup any old temp files.
ReplyDeleteIn other words, you are absolutely right there is no callback to tell me whether the email was actually sent... i did a combination of your options #1 and #2, I held onto them for a little while wasting space, then deleted the files risking the chance that the email had not yet been sent, hopefully my timing covered the actual use cases ok ;)