Is it possible to attach an Android res/drawable file to an email using Javamail?

Asked

Viewed 1,091 times

1

I’m looking for a two-way solution:

  • Get the file path:

I would like to get the path of an image that is in res/drawable on my Android project.

I’m in need of the path because I have to send it in attachment by email, and I’m using Javamail for this and he only accepts one path or a File, for attached file.

  • Getting Javamail to accept a Bitmap:

Change way of creating the email attachment, today I’m doing so:

MimeMultipart content = new MimeMultipart();
MimeBodyPart attachmentPart = new MimeBodyPart();
// aqui teria que setar um bitmap ao inves de um Path ou File;
attachmentPart.attachFile(attachment);
attachmentPart.setContentID("<image>");
attachmentPart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(attachmentPart);

I’ll try to explain the problem a little better:

I need this so that if I don’t find a user-configured logo (in a specific folder and with a specific name on sdcard) for email signature, then I would use a default logo from my application, and this default logo is available in my Sources (res/drawable)since he is unchanging.

I saw the solution that @ramaral posted, but although good, it’s not a solution that I expected, I believe there must be another way, because I have to make a copy of the image for sdcard. I don’t think "smell good".

Final solution with the help of the answers cited

Using the Bytearraydatasource as quoted by @Elcio Arthur Cardoso in his reply, I switched my method that includes the attachment to allow attaching a file on byte[] thus:

MimeMultipart content = new MimeMultipart();

// ... add message part

// converter bitmap to byte[]
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.transparent_1x1);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] imageBytes = stream.toByteArray();

// criar anexo do email, apartir de um array de byte (byte[])
MimeBodyPart attachmentPart = new MimeBodyPart();
DataHandler handlerAttach = new DataHandler(new ByteArrayDataSource(imageBytes));
attachmentPart.setDataHandler(handlerAttach);
attachmentPart.setFileName("image.png");
attachmentPart.setContentID("<image>");
attachmentPart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(attachmentPart);

That solution worked perfectly for my case.

3 answers

3

You cannot directly access the path or file because the resources are compiled together with the application.

What you can do is create a Bitmap from the resource.

Resources resources= getResources();
Bitmap bitMap = BitmapFactory.decodeResource(resources, R.drawable.image);

The Bitmap can be recorded in the SdCard, then you can send it by email. See here how to record.

  • even so from a Bitmap I can’t even get the path nor the File, to be able to set my Attachment. Or there is some way?

  • 1

    The Bitmap can be recorded in the SdCard. Behold here how to do

  • Thanks for the help, I managed to solve, from your tips and colleagues, check my solution and if you have tips for improvements, feel free to edit it.

3

Searching, I found a solution I couldn’t test because I’m not home...

At first, you can access your app’s drawable with a protocol-based URI android.resource.

To access a drawable through the File would be:

File image = new File("android.resource://package_do_app/"+ R.drawable.image);

As I said earlier, I couldn’t test, if the code doesn’t work I delete the answer. If I’m breaking any rules in the O.R., I apologize in advance.

The source is this question from SO OFFICIAL. Another source with more details.

From what was found, the above form is not uniform for all versions of Android.

Therefore, analyzing the documentation of the MimeBodyPart Javamail, there is a Constructor that receives a InputStream, and how on Android it is possible to get a InputStream from a Drawable strictly located in the folder raw.

To recover a InputStream from a Drawable that’s in the folder resource/raw I do it this way:

public class AssetsHelper {
    public static InputStream readRawResource(Context context, int rawResId) {
        return context.getResources().openRawResource(rawResId);
    }
}

From your code, I would do something like:

MimeBodyPart attachmentPart = new MimeBodyPart(AssetsHelper.readRawResource(getApplicationContext(), R.raw.transparent1x1);
//... Restante do código

Putting your image on res/raw should work.

  • I will test here and return, thank you for your attention.

  • That didn’t work here for me. It generated java.io.FileNotFoundException: /android.resource:/com.catalogo.app/2130837562: open failed: ENOENT (No such file or directory)

  • To create the File I did the following: file = new File(String.format("android.resource://%s/%s", this.getPackageName(), R.drawable.transparent1x1));, then I gave a .getAbsolutePath() to obtain the URI. Why didn’t it work for me?

  • I can test later, but looking at the second link, I think I made a mistake, maybe I need to put the type of Resource in the path. Type: File image = new File("android.resource://package_do_app/drawable/"+ R.drawable.image);. It’s like I said, I haven’t tested it yet, I can do it more the night.

  • @Fernando, I will do some tests to improve my answer.

  • I tested the @Wakim response and it worked for me. If you gave Filenotfoundexception, you are sure that transparent1x1 is in your drawable folder?

  • I think this varies from version to version, I tested with a Kitkat and it didn’t work... @Fernando, looking at the documentation of MimeBodyPart, it seems to me that it can do, but in a different way than the one I mentioned... I will prepare a code here and put here in the answer...

  • Thanks for the help, I managed to solve, from your tips and colleagues, check my solution and if you have tips for improvements, feel free to edit it.

Show 3 more comments

1


  • I’m testing your solution.

  • 1

    I solved from your answer, and posted in my question the final solution, if you want to add the solution to your answer to be clearer for future research please feel free. Or if you have any improvement, please share. I appreciate the help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.