1

My app has an option to send out the log, which is store in the app's secure storage. The path to the file is "/data/data/com.mycompany.myapp/files/log.zip". The file's permissions have been chnged to MODE_WORLD_READABLE, and the intent to launch email is:

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("application/zip");
i.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///data/data/com.mycompany.myapp/files/log.zip));
startActivity(Intent.createChooser(i, "Send Error Log"));

If the file is located on the SD card, there is no problem. But when it's secure storage, there is no attachment. I'm pretty sure that it's not a premissions issue because it works perfectly with the stock email client and with the TouchDown Exchange app. It's only Gmail that has this problem. Is this a glitch in Gmail, or am I missing something?

Thanks.

user496854
  • 6,461
  • 10
  • 47
  • 84
  • Can you obtain the Stream to the file directly and test your theory that way? – MJB May 01 '11 at 04:33
  • 1
    I know for a fact that the stream is accesible -- other email apps can access it and attach it with no problems – user496854 May 02 '11 at 06:24

4 Answers4

2

Yes, we can attach internal files stored in files directory to Gmail using FileProvider.Using FileProvider we can give temporary access to some of our app's internal files(as mentioned in filepaths.xml)

In the manifest as mentioned in the Android documentation add a FileProvider:

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

Now in your app's res/xml folder create filepaths.xml, and add the following code:

 <paths>
 <files-path path="." name="name" />

Note:This will give access to the root files directory, if you want to give specific access to some subdirectory, say images, in your internal storage mention the path as "images/"

    <paths>
    <files-path path="images/" name="name" />

In the code:

File file=new File(context.getFilesDir(),"test.txt");

Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);

shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
                                 "Test");

shareIntent.setType("text/plain");

shareIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
                             new String[] {"email-address you want to send the file to"});

Uri uri = FileProvider.getUriForFile(context,"com.package.name.fileprovider",
                                               file);

            ArrayList<Uri> uris = new ArrayList<Uri>();
            uris.add(uri);

            shareIntent .putParcelableArrayListExtra(Intent.EXTRA_STREAM,
                                                    uris);


            try {
               context.startActivity(Intent.createChooser(shareIntent , "Email:").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));                                                      


            }
            catch(ActivityNotFoundException e) {
                Toast.makeText(context,
                               "Sorry No email Application was found",
                               Toast.LENGTH_SHORT).show();
            }
        }

This worked for me.Hope this helps :)

Adarsh Chithran
  • 218
  • 3
  • 6
1

Nevermind, I found the answer -- Gmail does not allow any attachments unless they come from the SD card. I ended up having to copy the file to external storage cachce, and then everything worked. It sucks that Gmail arbitrarily decides that it won't use files on insternal storage, even if permissions are correct!

user496854
  • 6,461
  • 10
  • 47
  • 84
  • 1
    Anyone find another way around this issue? (what if they don't have and SD card?) – TChadwick Oct 19 '12 at 20:22
  • 1
    @TChadwick take a look at this answer http://stackoverflow.com/a/18332000/1082344 I was able to attach files from my app's secure storage to Gmail using the FileProvider class from support library and manually granting and revoking permissions for my files. – IsaacCisneros Feb 28 '14 at 11:01
  • 1
    This is not true. Using a FileProvider you can share via Gmail. – neteinstein Jan 23 '15 at 18:10
0

Gmail client app attachments finally now works on android 4.0+ devices. i've tested on my 4.2 and 4.3 devices and they work.

I have verified with my moto razr 2.3 that the gmail client does NOT work. using another mail client works just fine, so your answer as of 2011 was correct.

David T.
  • 22,301
  • 23
  • 71
  • 123
0

AndroidManifest.xml

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

res/xml/path.xml

     <?xml version="1.0" encoding="utf-8"?>
     <paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="files" path=""/>
    </paths>

your activity file should have following intent :

    Uri log_file_uri = null;
    Uri logcat_file_uri = null;
    String log_filePath = activity.getApplicationContext().getFilesDir().getPath()
    + "/"+ activity.getApplicationContext().getResources().getString(R.string.log_file);
    String logcat_filePath = activity.getApplicationContext().getFilesDir()
    .getPath()+ "/"+ activity.getApplicationContext().getResources().getString(R.string.logcat_file);
    File log_file = new File(log_filePath);File logcat_file = new File(logcat_filePath);
    if (log_file.exists() && logcat_file.exists()) {
    log_file_uri = FileProvider.getUriForFile(
    activity.getApplicationContext(),"com.example.LogFileShare",log_file);
    logcat_file_uri = FileProvider.getUriForFile(
    activity.getApplicationContext(),"com.example.LogFileShare",logcat_file);
Suyog Gunjal
  • 287
  • 4
  • 7