2

I can't attach an image file located in my cache to an email Intent.

My code :

Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(Intent.EXTRA_SUBJECT, DPLabelTV.getText());
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "" });

String image_key = mCache.getKey(Uri.parse(url));
File image_file = mCache.getFile(image_key);
Uri uri = Uri.fromFile(image_file);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);                                                                                                                 
emailIntent.putExtra(Intent.EXTRA_TEXT, "Hello world");
startActivity(Intent.createChooser(emailIntent, "Send email..."));

The output of uri is: file:///data/data/com.mypackage/cache/cf3dd860d5e9562512f699c9cccb2d16a3cdaa8f.jpg

I already tried this :

emailIntent.setType("application/image");
emailIntent.setType("image/jpeg");

Manifest permissions :

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

The error message I get is :

W/Gmail   ( 4542): Error opening file to obtain size.
W/Gmail   ( 4542): java.io.FileNotFoundException: Permission denied
I/Gmail   ( 4542): Unable to get orientation of thumbnail file:///data/data/com.mypackage/cache/cf3dd860d5e9562512f699c9cccb2d16a3cdaa8f.jpg: class java.io.FileNotFoundException         /data/data/com.mypackage/cache/cf3dd860d5e9562512f699c9cccb2d16a3cdaa8f.jpg: open failed: EACCES (Permission denied)

Anyone has a clue?

EDIT FROM 28/01/14

New code :

        // Grant permissions to all apps that can handle this intent
        List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(emailIntent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList)
        {
            String packageName = resolveInfo.activityInfo.packageName;
            grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }

        startActivity(Intent.createChooser(emailIntent, "Send email..."));

Manifest :

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

XML path file :

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

and still not working...

thomaus
  • 6,170
  • 8
  • 45
  • 63
  • Possible duplicate of [Sharing files or content with 3rd party activities](http://stackoverflow.com/questions/21342722/sharing-files-or-content-with-3rd-party-activities). Also note that the MIME type for plain text is `text/plain`, not `plain/text`. – CommonsWare Jan 27 '14 at 18:56
  • Ran into same issue while working on share a local PDF file. Found this solution to get a basic FileProvider setup going using a minimal github example project: stackoverflow.com/a/48103567/2162226 , where adding and sending an attachment is part of the code there . It provides steps for which files to copy over (without making changes) into a local standalone project – Gene Bo Jan 04 '18 at 21:39

4 Answers4

1

You cannot simply pass the file path of a file that lies in your app's folder. Files in that folder can only be accessed by your app.

You'll have to implement a ContentProvider for allowing external apps to access your files.

This will get you started: http://developer.android.com/guide/topics/providers/content-provider-basics.html

For files, you can also use FileProvider: http://developer.android.com/reference/android/support/v4/content/FileProvider.html

FD_
  • 12,947
  • 4
  • 35
  • 62
  • Thanks. Can you provide me simple and efficient code to implement this ContentProvider ? – thomaus Jan 27 '14 at 19:50
  • 1
    Have a look at FileProvider, a subclass of ContentProvider that already does what you need. – FD_ Jan 27 '14 at 20:14
1

Data from your app can not be accessed by other apps. A quick solution is to copy the file to the external folder and once you get the result back from the email activity, delete the external file.

String oldPath = ...;
String newPath = getExternalCacheDir() + "/" + UUID.randomUUID();

// Copy the file from old path to new path
...

Uri uri = Uri.fromFile(image_file);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);                                                                                                                 
emailIntent.putExtra(Intent.EXTRA_TEXT, "Hello world");
startActivity(Intent.createChooser(emailIntent, "Send email..."));

public void onActivityResult(int requestCode, int resultCode, final Intent data) {
    // Delete the newPath file
}
Aswin Rajendiran
  • 3,399
  • 1
  • 21
  • 18
0

After many intents, here is the answer that worked for me : Android attach image to email doesn't work

You just need to copy the image to the external storage and then attach this new image.

Community
  • 1
  • 1
thomaus
  • 6,170
  • 8
  • 45
  • 63
-1

I know it is deprecated but still works as of v4.4.4. Just put your file into context.getFilesDir() and specify world readable flag

FileOutputStream fos = context.openFileOutput(LOG_FILE_NAME, Context.MODE_WORLD_READABLE);
fos.write(...);
fos.close();

Then use this location to attach the file

String attachment = context.getFileStreamPath(LOG_FILE_NAME).getAbsolutePath();
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + attachment));
ievgen
  • 1,081
  • 11
  • 20